引言:對(duì)于一些跨國(guó)項(xiàng)目來(lái)說(shuō),國(guó)際化是尤為重要的己英,那么什么要國(guó)際化呢?國(guó)際化的意思就是將我們寫(xiě)的項(xiàng)目间螟,能夠根據(jù)不同國(guó)家的語(yǔ)言,進(jìn)行翻譯损肛,進(jìn)行切換寒亥,方便不同國(guó)家的客戶使用。
本文展示了在vue中如何使用國(guó)際化來(lái)更改咱們的項(xiàng)目語(yǔ)言荧关,首先我們需要安裝i18n這個(gè)插件
1、i18n
1.1褂傀、i18n的安裝
i18n
是internationalization
這個(gè)單詞的縮寫(xiě)忍啤,取了首字母i
和結(jié)尾字母n
,中間一用有18個(gè)字母仙辟,所以組合起來(lái)就所寫(xiě)成i18n
同波,這是一個(gè)用于給vue國(guó)際化的插件, 它可以輕松地將一些本地化功能集成到你的 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)中使用它未檩,必須通過(guò) 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)備翻譯的語(yǔ)言環(huán)境信息
const messages = {
en: {
message: {
hello: 'hello world'
}
},
ja: {
message: {
hello: 'こんにちは、世界'
}
}
}
// 通過(guò)選項(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)容
接下來(lái)悲雳,我們需要將這個(gè)i18n實(shí)例
掛載在Vue
的option中
import Vue from 'vue'
import i18n from "./src/i18n/index.js"
new Vue({
i18n
})
那么如何在視圖中呈現(xiàn)呢,其實(shí)也很簡(jiǎn)單香追,我們只需要在插值中使用$t
這個(gè)函數(shù)就可以了
<div id="app">
<p>{{ $t("message.hello") }}</p>
</div>
最終展示的效果是
<div id="app">
<p>hello world</p>
</div>
是不是很簡(jiǎn)單合瓢,當(dāng)然這是咱們對(duì)i18n最基礎(chǔ)的使用,如果想要更深入的使用透典,可以查看
開(kāi)始 | 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)前的例子只提供兩種語(yǔ)言(多了寫(xiě)的累-_-||)税弃,分別是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)行了配置,接下來(lái)茸时,我們來(lái)配置下/src/i18n/index.js
文件贡定,我們?cè)陂_(kāi)發(fā)過(guò)程中都知道,如果一個(gè)路由或者api有很多內(nèi)容都寫(xiě)在一個(gè)文件可都,容易造成維護(hù)災(zāi)難缓待,繼續(xù)秉承高內(nèi)聚低耦合的思路,我們和對(duì)項(xiàng)目中的路由或者api進(jìn)行model劃分渠牲,本文中的兩個(gè)語(yǔ)言配置en
和zh
也是劃分模塊旋炒,但是如果我們有20幾個(gè)國(guó)家
的語(yǔ)言需要翻譯,我們?cè)趇ndex中一個(gè)一個(gè)的import
顯然對(duì)開(kāi)發(fā)效率來(lái)書(shū)是中災(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è)問(wèn)題瘫镇,本文采用了webpack
中的require.context
方法來(lái)解決這個(gè)問(wèn)題
2.4、使用require.context()
require.context
是webpack提供的方法答姥,用這個(gè)方法我們可以批量引入我們想要的文件铣除,require.context
可以返回一個(gè)具有 resolve, keys鹦付, id 三個(gè)屬性的方法
-
resolve()
它返回請(qǐng)求被解析后得到的模塊 id -
keys()
它返回一個(gè)數(shù)組尚粘,由所有符合上下文模塊處理的請(qǐng)求組成 - id 是上下文模塊里面所包含的模塊 id. 它可能在你使用
module.hot.accept
的時(shí)候被用到
這個(gè)方法接受3個(gè)參數(shù)
-
dir
傳入一個(gè)目錄進(jìn)行搜索 <String> -
child
是否要搜索子目錄<Boolean> -
regExp
傳入正則表達(dá)式來(lái)匹配哪些文件需要引入<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
的簡(jiǎn)單使用,如果想要知道更詳細(xì)的用法敲长,那我后續(xù)會(huì)再開(kāi)一期關(guān)于require.context
的專題郎嫁,敬請(qǐng)期待
2.5、繼續(xù)配置/src/i18n/index.js
下面的代碼中我使用了一個(gè)正則表達(dá)式
let reg = /^\.\/([^\.]+)\.([^\.]+)$/ //正則用于匹配文件名
用這個(gè)正則的目的是為了祈噪,我們需要將數(shù)據(jù)處理成這樣
{
zh:{...}行剂,
en:{...}
}
處理成這種i18n
中message
屬性對(duì)應(yīng)的數(shù)據(jù)模式,我們通過(guò)forEach
獲取下來(lái)的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吓坚,//指定語(yǔ)言字段
messages//定義語(yǔ)言字段
})
2.6撵幽、修改main.js
下面我們將i18n掛載在main的Vue實(shí)例,本案例中也引入了element-ui礁击,如果想要使用element-ui盐杂,需要先安裝
yarn add element-ui
接下來(lái)根據(jù)自己的需求編寫(xiě)代碼
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á)到快速的演示效果厉斟,但是如果我們?cè)陂_(kāi)發(fā)中的話要通過(guò)計(jì)算機(jī)的語(yǔ)言來(lái)判斷,并且進(jìn)行切換强衡,正確的方法是我們通過(guò)navigator.language
來(lái)獲取計(jì)算機(jī)的語(yǔ)言
<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、效果
表頭的翻譯效果 此處多加了兩種語(yǔ)言