【Vue】 欸欸來切換語言啊 (Vue 3 搭配 Vue CLI 與 i18n)

本篇大綱:

  1. 環境設置
  2. 準備多語言檔案
  3. 檔案設定
  4. 在 component 中使用
  5. 其他資料格式

簡介

這是一篇 Vue3 搭配 Vue CLI 使用 i18n 來切換網站語言的栗子。

環境設置

  • node : v14.17.1
  • vue : “^3.0.0”
  • vue-cli : “~4.5.0”
  • vue-i18n : “^9.1.7”

安裝 i18n

Vue I18n

1
npm install vue-i18n@next

檔案架構

1
2
3
4
5
6
7
8
9
src
├- i18n.js //設定 i18n 檔案
├- i18n
├-- tw.json //中文翻譯
├-- en.json //英文翻譯
├- components
├-- HelloWorld.vue
├- App.vue
├- main.js

準備多語言檔案

使用 json 檔案儲存個別語言對應的名詞,這裡準備了 zh-TW (繁體中文) 和 en-US (英文) 兩種語言。

1
2
3
4
5
6
7
8
//filename : tw.json

{
"name": "姓名",
"gender": "性別",
"email" : "電郵",
"address": "地址"
}
1
2
3
4
5
6
7
//filename : en.json
{
"name": "Name",
"gender": "Gender",
"email" : "Email",
"address": "Address"
}

檔案設定

設定 i18n 檔案

需要使用 createI18n 來設定,其中需要 3 個參數 : locale (設定語言)、 fallbacakLocale ( 如果翻譯失敗使用的語言 )、messages ( 各個語言翻譯的檔案 )。

這裡為了方便起見所以使用 json 檔案來儲存各語言的翻譯,再引入到 messages 裡。

因為沒有另外建立 store 來儲存語言這個變數,因此語言設定從 local storage 中的 language 中取得,也可以將預設語言設定為電腦本身的語言 : let lang = navigator.language || 'tw' .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//filename: i18n.js

import { createI18n } from "vue-i18n" //引入 createI18n

//引入需要的 json 檔案
const messages = {
"en-US" : require('./i18n/en.json'),
"zh-TW" : require('./i18n/tw.json')
}

//設定語言,從 local storage 取得
const lang = localStorage.getItem('language') || 'zh-TW'

const i18n = createI18n({
locale: lang, // set locale
fallbackLocale: 'en-US', // set fallback locale
messages
})

export default i18n

在 main.js 中引入套件

Vue 3 和 Vue 2 的使用插件有些不一樣,在開始找資料的時候多找到 Vue2 的寫法,然後弄了很久才發現 Vue 2 和 Vue 3 寫法不一樣啊啊啊(Vue 小白的煩惱 QAQ)。

1
2
3
4
5
6
7
8
9
//main.js

import { createApp } from 'vue'
import App from './App.vue'
import i18n from './i18n'

const app = createApp(App)
app.use(i18n)
app.mount('#app')

在 component 中使用

這部分參考 在 Vue-cli 中使用 i18n 實作多國語系 | Eason Lin

在設定好上面兩個檔案之後,就可以在任何 component 中使用這個套件。只要使用 $t 符號,就可以插入需要的文字,且只需要撰寫一次 template 就可以通過轉換語言 lang 變數來達到翻譯的效果。

1
<p>{{ $t("pageTitleText") }}</p>

設定了兩個按鈕來更換語言,點擊 tw 按鈕時會觸發 setLang function, 把變數 lang 的傳到 setActiveLanguage 這個 fucntion. 而 setActiveLanguage 則會更新 local storage language 中的值,從而達到更新語言的目的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// filename : HelloWorld.vue

<template>
<div class="hello">
<div>hellllo</div>
<p>{{ $t("pageTitleText") }}</p>
<button data-lang="zh-TW" @click="setLang">tw</button>
<button data-lang="en-US" @click="setLang">en</button>
</div>
</template>

<script>
export default {
name: 'HelloWorld',
methods: {
setActiveLanguage(lang) {
localStorage.setItem('language', lang)
},
setLang(event) {
const lang = event.target.dataset.lang
this.setActiveLanguage(lang)
return history.go(0)
}
}
}
</script>

這是基本的使用方式,i18n 也接受不同的資料撰寫格式,在使用上提供了更大的彈性。

其他資料格式

Interpolations

Interpolations : Named interpolation

可以在資料裡使用花括號 {}, 插入到 component 內時,可以自己定義 msg 的值。

1
2
3
4
//json
{
"first": "{msg} world",
}
1
2
3
//html
<p>{{ $t("first", { msg: 'hello' }) }}</p>
//輸出 : hello world

Interpolations : List interpolation

花括號裡的數字是 array 的 index. 在 component 中傳入一個 array 就可以指定要輸出哪一個 item.

1
2
3
4
//json
{
"first": "{1} world",
}
1
2
3
//html
<p>{{ $t("first", ['hello', 'bye']) }}</p>
//輸出 : bye world

Interpolations : Literal Interpolation

設定好需要的區塊,在把資料傳進去。在花括號裡加上單引號就會被認為是字串。

1
2
3
4
//json
{
"email": "{account}{'@'}{domain}",
}
1
2
3
//html
<p>{{ $t("email", {account: 'hello', domain: 'mail.com'}) }}</p>
//輸出 : hello@mail.com

Linked messages

在資料裡串接資料,使用方式是加上 @ , 然後接上所需要的資料。

1
2
3
4
5
6
7
8
//json
{
"msg":{
"the_world": "the world",
"dio": "DIO",
"linked": "@:msg.dio @:msg.the_world !!!"
} ,
}
1
2
3
//html
<p>{{ $t("msg.linked") }}</p>
//輸出 : DIO the world !!!

小結

因為實習的專案中遇到了多國語言轉換的問題,因此看了一些資料實作看看。當然專案中不只是這基礎的操作,還有一些較為複雜的部分,之後可能會再回來更新一些遇到的坑。

參考資料

Vue I18n
在 Vue-cli 中使用 i18n 實作多國語系(Vue2) medium

Comments