Vue 項目前端多語言方案
作者:Paian
http://mobilesite.github.io
一、通常有哪些內(nèi)容需要處理
<template>標(biāo)簽中的文字內(nèi)容title二、基本思路
1、首先,需要確定以什么樣的方式來獲取到當(dāng)前應(yīng)該展示何種語言
?lang=en或者?lang=zh-CN這樣的傳遞參數(shù)的形式。這樣做的好處在于可以通過鏈接指定用哪種語言。但是,只依賴于地址欄參數(shù)也是不方便的。比如,在頁面跳轉(zhuǎn)的時候,這個地址欄參數(shù)可能就丟失了。這會導(dǎo)致你在頁面跳轉(zhuǎn)之后就不知道該用哪種語言展示了。而理想的的方式應(yīng)該是,進入某個頁面的時候帶有這個參數(shù)(這個時候就獲取到該使用何種語言了),等再跳轉(zhuǎn)到其它頁面的時候就不必再帶這個lang參數(shù)了,因為此時你已經(jīng)知道該用哪種語言了。所以,應(yīng)該在一進入第一個頁面的時候就把這個參數(shù)存下來,比如,存在localstorage中,存在vuex的state中。lang參數(shù),localstorage中可能也有相關(guān)的存儲字段(因為上次訪問過本應(yīng)用),你可能還想設(shè)置默認的降級語言,等等。其優(yōu)先級應(yīng)該如何處理呢?navigator.language獲取瀏覽器默認語言,看是否是你的應(yīng)用所支持的語言,若是,則采用之;2、其次,采用什么工具來解決語言轉(zhuǎn)換和打包的問題?
<span>$t('真實姓名', 'Real Name')</span>
this.$t('真實姓名', 'Real Name')
import i18n from 'simplest-i18n';
import getLang from '../../getLang';
const t = i18n({
locale: getLang.lang, // 當(dāng)前語言
locales: getLang.langs // 支持的語言列表
});
export default t;
import t from './t';
Vue.$t = Vue.prototype.$t = t;
$t這個方法掛載到了Vue.js的全局。Vue實例中也可以通過this.$t訪問到,使用上還是非常簡單的。confirm:
zh-CN: 確認
en: confirm
confirm: 確認
confirm: confirm
<i18n>標(biāo)簽。比如,在自定義組件中我可以這么寫:<i18n>
confirm:
zh-CN: 確認
en: confirm
<i18n>
<i18n>標(biāo)簽中的多語言配置信息導(dǎo)出至我們所配置的一個Yaml文件中,而把<i18n>標(biāo)簽從我們的自定義組件中移除。const componentsLocales = require('json-loader!yaml-loader!../../locales/components.yml'); // 這就得到了一個語言包的json格式
3、如何通知后端接口返回何種語言的數(shù)據(jù)?
Accept-Language, 并把這個值的內(nèi)容設(shè)置成前端所獲得應(yīng)使用的語言(如,zh-CN 或 en 等)。這樣,就集中在一處把這個問題處理掉了。三、具體實踐中的一些細節(jié)
1、獲取當(dāng)前應(yīng)該采用何種語言的getLang模塊的實現(xiàn)
import { getQueryObj } from '../utils/url';
import { setItem, getItem } from '../utils/storage';
const langs = ['zh-CN', 'en']; // 支持哪些語言
const defaultLang = 'en'; // 默認語言,暫時并沒有對外拋出
function getLang() {
let queries = getQueryObj();
let storeLang = getItem('lang');
let rawLang;
let flag = false;
if (queries && queries['lang']) {
rawLang = queries['lang'];
setItem('lang', rawLang);
} else {
rawLang = storeLang || navigator.language;
}
langs.map(item => {
if (item === rawLang) {
flag = true;
}
});
return flag ? rawLang : defaultLang;
}
const lang = getLang(langs, defaultLang);
export default {
lang, // 獲取到當(dāng)前語言
langs // 所支持的語言列表
}
2、Vux組件的多語言包的配置
src/locales/all.yml拷貝過來(同一目錄下的src/locales/zh-CN.yml、src/locales/en.yml分別是其中文部分和英文部分),根據(jù)你自己的需要略作修改即可。const vuxLocales = require('json-loader!yaml-loader!../../locales/all.yml');
3、vux-loader的配置
webpack.dev.conf.js中:resolve(vuxLoader.merge(devWebpackConfig, {
plugins_dir: [
'vux-ui',
{
name: 'i18n',
vuxStaticReplace: false,
staticReplace: false,
extractToFiles: 'src/locales/components.yml',
localeList: ['en','zh-CN']
}
]
}))
resolve(vuxLoader.merge(buildWebpackConfig, {
plugins_dir: [
'vux-ui',
{
name: 'i18n',
vuxStaticReplace: false,
staticReplace: false,
extractToFiles: 'src/locales/components.yml',
localeList: ['en','zh-CN']
}
]
}))
localeList: ['en','zh-CN']就是指定你的應(yīng)用支持哪幾種語言。extractToFiles: 'src/locales/components.yml'就是指定你的自定義組件中所用到的那些<i18n>標(biāo)簽中的語言包信息,應(yīng)該導(dǎo)出到哪個Yaml文件中。也就是說,你在各個自定義組件中使用的<i18n>標(biāo)簽中的語言包信息都會被vux-loader集中抽取到這個文件中。const componentsLocales = require('json-loader!yaml-loader!../../locales/components.yml');
4、自定義組件內(nèi)外文案的多語言化
<i18n>標(biāo)簽中即可。同時,為了避免不同的自定義組件中多語言字段的命名沖突,在每個字段的名字前面加上以組件名-式的前綴。<i18n>標(biāo)簽中,所以我們單獨新建一個global.yml來存放這些全局性的多語言信息。這些內(nèi)容直接寫在global.yml中即可,并且,為了表面與其它的語言包字段相沖突,我們在每個字段的前面加上global-前綴。const componentsLocales = require('json-loader!yaml-loader!../../locales/global.yml');
5、vuex-i18n的實現(xiàn)
import VuexI18n from 'vuex-i18n';
export default new Vuex.Store中增加:i18n: VuexI18n.store
import VuexI18n from 'vuex-i18n';
import getLang from '../../getLang';
Vue.use(VuexI18n.plugin, store);
const vuxLocales = require('json-loader!yaml-loader!../../locales/all.yml');
const componentsLocales = require('json-loader!yaml-loader!../../locales/components.yml');
const finalLocales = {
'en': Object.assign(vuxLocales['en'], componentsLocales['en']),
'zh-CN': Object.assign(vuxLocales['zh-CN'], componentsLocales['zh-CN'])
}
for (let i in finalLocales) {
Vue.i18n.add(i, finalLocales[i])
}
Vue.i18n.set(globalVars.lang);
6、圖片的多語言化
7、在當(dāng)前頁面通過按鈕切換當(dāng)前語言后,如何更新當(dāng)前頁面的內(nèi)容?
lang參數(shù)就可以了,并不涉及到此問題。<button @click="changeLang('zh-CN')">中文</button>
<button @click="changeLang('en')">英文</button>
changeLang(lang){
location.href = this.$utils.url.replaceParam(this.$router.history.current.path, 'lang', lang);
},
lang字段的變化,通過v-if局部刷新某些相關(guān)組件:data(){
return {
lang: this.$i18n.locale()
}
}
changeLang(lang){
this.$i18n.set(lang);
this.lang = this.$i18n.locale();
},
watch: {
lang(newVal, oldVal) {
if(newVal === oldVal) {
return;
}
// 在這里通過改變某個標(biāo)志位 結(jié)合 v-if 來觸發(fā)某個局部組件的重新渲染
}
}
8、Yaml中特殊字符的轉(zhuǎn)義
[、]等,需要進行轉(zhuǎn)義。轉(zhuǎn)的方式是給鍵值加上單引號引起來。str: 'labor''s day'
逆鋒起筆是一個專注于程序員圈子的技術(shù)平臺,你可以收獲最新技術(shù)動態(tài)、最新內(nèi)測資格、BAT等大廠的經(jīng)驗、精品學(xué)習(xí)資料、職業(yè)路線、副業(yè)思維,微信搜索逆鋒起筆關(guān)注!
評論
圖片
表情
