引言:對(duì)于一些跨國項(xiàng)目來說,國際化是尤為重要的,那么什么要國際化呢?國際化的意思就是將我們寫的項(xiàng)目,能夠根據(jù)不同國家的語言,進(jìn)行翻譯,進(jìn)行切換,方便不同國家的客戶使用。
本文展示了在vue中如何使用國際化來更改咱們的項(xiàng)目語言,首先我們需要安裝i18n這個(gè)插件
1、i18n
1.1、i18n的安裝
i18n是internationalization這個(gè)單詞的縮寫,取了首字母i和結(jié)尾字母n,中間一用有18個(gè)字母,所以組合起來就所寫成i18n,這是一個(gè)用于給vue國際化的插件, 它可以輕松地將一些本地化功能集成到你的 Vue.js 應(yīng)用程序中
安裝 | Vue I18n?kazupon.github.io
//使用yarn
yarn add vue-i18n
//npm
npm i vue-i18n -S
1.2、i18n基本使用
如果在一個(gè)模塊系統(tǒng)中使用它,必須通過 Vue.use() 明確地安裝 vue-i18n:
假如當(dāng)前的目錄是src/i18n/index.js
//src/i18n/index.js
import Vue from 'vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
// 準(zhǔn)備翻譯的語言環(huán)境信息
const messages = {
en: {
message: {
hello: 'hello world'
}
},
ja: {
message: {
hello: 'こんにちは、世界'
}
}
}
// 通過選項(xiàng)創(chuàng)建 VueI18n 實(shí)例
const i18n = new VueI18n({
locale: 'ja', // 設(shè)置地區(qū)
messages // 設(shè)置地區(qū)信息
})
上面代碼中的messages對(duì)象中有兩個(gè)屬性,屬性名分別是en和ja其實(shí)在i18n中這兩個(gè)字段是和下面new VueI18n實(shí)例中的locale里的值相對(duì)應(yīng)的,而messages對(duì)象又作為了new VueI18n的實(shí)例屬性,所以當(dāng)locale的值是ja的時(shí)候,那么會(huì)加載messages.ja這個(gè)對(duì)象中的內(nèi)容
接下來,我們需要將這個(gè)i18n實(shí)例掛載在Vue的option中
import Vue from 'vue'
import i18n from "./src/i18n/index.js"
new Vue({
i18n
})
那么如何在視圖中呈現(xiàn)呢,其實(shí)也很簡單,我們只需要在插值中使用$t這個(gè)函數(shù)就可以了
<div id="app">
<p>{{ $t("message.hello") }}</p>
</div>
最終展示的效果是
<div id="app">
<p>hello world</p>
</div>
是不是很簡單,當(dāng)然這是咱們對(duì)i18n最基礎(chǔ)的使用,如果想要更深入的使用,可以查看
開始 | Vue I18n?kazupon.github.io
2、在vue-cli項(xiàng)目中使用
2.1、創(chuàng)建i18n文件結(jié)構(gòu)
我們首先在項(xiàng)目中src目錄下建立一個(gè)叫做i18n的文件夾,路徑為/src/i18n 當(dāng)前的例子只提供兩種語言(多了寫的累-_-||),分別是en英文和zh中文,格式如下建立就可以了,我們秉承著高內(nèi)聚低耦合的思路,所以把原本i18n實(shí)例中messages中的屬性進(jìn)行模塊化拆分為兩個(gè)文件,如下圖,都放置在config文件夾中

2.2、config中兩個(gè)文件的內(nèi)容定義
en.js和zh.js我們可以先定義一些內(nèi)容
en.js
export default {
table: {//假如用于翻譯表格
date: "Date",
name: "Name",
address: "Address"
},
menu: {},//假如項(xiàng)目中日后還有菜單
tabs: {}//tab切換等
}
zh.js
export default {
table: {
date: "日期",
name: "姓名",
address: "地址"
},
menu: {},
tabs: {}
}
2.3、配置i18n文件夾下的index.js文件
目前我們已經(jīng)對(duì)兩個(gè)js文件進(jìn)行了配置,接下來,我們來配置下/src/i18n/index.js文件,我們在開發(fā)過程中都知道,如果一個(gè)路由或者api有很多內(nèi)容都寫在一個(gè)文件,容易造成維護(hù)災(zāi)難,繼續(xù)秉承高內(nèi)聚低耦合的思路,我們和對(duì)項(xiàng)目中的路由或者api進(jìn)行model劃分,本文中的兩個(gè)語言配置en和zh也是劃分模塊,但是如果我們有20幾個(gè)國家的語言需要翻譯,我們在index中一個(gè)一個(gè)的import顯然對(duì)開發(fā)效率來書是中災(zāi)難,我們的代碼可能這樣
import en from './config/en'
import id from './config/id'
import ja from './config/ja'
import ae from './config/ae'
import am from './config/am'
import ca from './config/ca'
import al from './config/al'
.....
為了解決這個(gè)問題,本文采用了webpack中的require.context方法來解決這個(gè)問題
2.4、使用require.context()
require.context是webpack提供的方法,用這個(gè)方法我們可以批量引入我們想要的文件,require.context可以返回一個(gè)具有 resolve, keys, id 三個(gè)屬性的方法
-
resolve()它返回請求被解析后得到的模塊 id -
keys()它返回一個(gè)數(shù)組,由所有符合上下文模塊處理的請求組成 - id 是上下文模塊里面所包含的模塊 id. 它可能在你使用
module.hot.accept的時(shí)候被用到
這個(gè)方法接受3個(gè)參數(shù)
-
dir傳入一個(gè)目錄進(jìn)行搜索 <String> -
child是否要搜索子目錄<Boolean> -
regExp傳入正則表達(dá)式來匹配哪些文件需要引入<RegExp>
let langFiles = require.context("./config", false, /\.js$/);
當(dāng)我們調(diào)用kes()方法的時(shí)候可以得到如下屬性
let langFiles = require.context("./config", false, /\.js$/);
console.log(langFiles.keys())//["./cn.js","./zh.js"]
以上便是require.context的簡單使用,如果想要知道更詳細(xì)的用法,那我后續(xù)會(huì)再開一期關(guān)于require.context的專題,敬請期待
2.5、繼續(xù)配置/src/i18n/index.js
下面的代碼中我使用了一個(gè)正則表達(dá)式
let reg = /^\.\/([^\.]+)\.([^\.]+)$/ //正則用于匹配文件名
用這個(gè)正則的目的是為了,我們需要將數(shù)據(jù)處理成這樣
{
zh:{...},
en:{...}
}
處理成這種i18n中message屬性對(duì)應(yīng)的數(shù)據(jù)模式,我們通過forEach獲取下來的key是這種類型的./zh.js使用正則的目的就是截取其中的zh兩個(gè)字符,然后生成復(fù)合message屬性的數(shù)據(jù)模型
import Vue from "vue"
import VueI18n from "vue-i18n"
Vue.use(VueI18n)//注入到所有的子組件
//require.context(path,deep,regExp)
//有3個(gè)方法 分別是keys()
let langFileds = require.context('./config', false, /\.js$/)
let regExp = /\.\/([^\.\/]+)\.([^\.]+)$/ //正則用于匹配 ./en.js中的'en'
// regExp.exec('./en.js')
let messages = {} //聲明一個(gè)數(shù)據(jù)模型,對(duì)應(yīng)i18n中的message屬性
langFileds.keys().forEach(key => {
let prop = regExp.exec(key)[1] //正則匹配en|zh這樣的值
//messages[prop]相當(dāng)于 messages['en'] = {table:{...}}
messages[prop] = langFileds(key).default
})
console.log(messages);
console.log(langFileds('./en.js'));
let locale = localStorage.getItem('lang') || "zh" //從localstorag中獲取
export default new VueI18n({
locale,//指定語言字段
messages//定義語言字段
})
2.6、修改main.js
下面我們將i18n掛載在main的Vue實(shí)例,本案例中也引入了element-ui,如果想要使用element-ui,需要先安裝
yarn add element-ui
接下來根據(jù)自己的需求編寫代碼
import Vue from 'vue'
import App from './App.vue'
import ElementUI from "element-ui" //element-ui
import 'element-ui/lib/theme-chalk/index.css';
Vue.config.productionTip = false
Vue.use(ElementUI)
import i18n from "./i18n" //
new Vue({
render: h => h(App),
i18n //掛載
}).$mount('#app')
2.7、 App.vue視圖展示(navigator.language)
從2.5的代碼中我們可以看到,我將locale的屬性設(shè)置為從localStorage中獲取,是為了達(dá)到快速的演示效果,但是如果我們在開發(fā)中的話要通過計(jì)算機(jī)的語言來判斷,并且進(jìn)行切換,正確的方法是我們通過navigator.language來獲取計(jì)算機(jī)的語言
<template>
<div id="app">
<template>
<el-table :data="tableData"
style="width: 100%">
<el-table-column prop="date"
:label="$t('table.date')"
width="180">
</el-table-column>
<el-table-column prop="name"
:label="$t('table.name')"
width="180">
</el-table-column>
<el-table-column prop="address"
:label="$t('table.address')">
</el-table-column>
</el-table>
</template>
<el-button type="primary"
@click="change('zh')">點(diǎn)擊切換中文</el-button>
<el-button type="primary"
@click="change('en')">點(diǎn)擊切換英文</el-button>
<el-button type="primary"
</div>
</template>
<script>
export default {
mounted() {
console.log(this.$i18n.t('table.date'));
},
methods: {
change(lang) { //切換方法
localStorage.setItem('lang', lang)
window.location.reload() //localSotrage是不響應(yīng)的,為了演示效果所以直接調(diào)用刷新
}
},
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀區(qū)金沙江路 1518 弄'
}, {
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀區(qū)金沙江路 1517 弄'
}, {
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀區(qū)金沙江路 1519 弄'
}, {
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀區(qū)金沙江路 1516 弄'
}]
}
}
}
</script>
<style>
#app {
width: 50%;
}
</style>
2.8、效果
表頭的翻譯效果 此處多加了兩種語言
