多語言(i18n)支持 是企業(yè)項(xiàng)目走向國際化的必經(jīng)之路,也是前端工程師最佳實(shí)踐的內(nèi)容之一。不過,多語言框架眾多,會(huì)帶來一系列選型問題,相信大家在平時(shí)對(duì)項(xiàng)目進(jìn)行多語言支持時(shí),也往往會(huì)遇到如下幾個(gè)問題:
針對(duì)不同的技術(shù)棧,我該如何選擇多語言方案?
如果不借助第三方庫,如何獨(dú)立實(shí)現(xiàn)對(duì)項(xiàng)目的多語言支持?
在實(shí)踐多語言方案的過程中,我因該考慮那些問題? 如何更高效的實(shí)現(xiàn)多語言?
其實(shí),多語言框架雖多,但是從傳統(tǒng)的 jquery 時(shí)代到目前流行的 MVVM 框架,多語言方案一直在演進(jìn)和優(yōu)化,最終目的是將其普適化和最簡化。理解了這一點(diǎn),學(xué)習(xí)多語言技術(shù)就容易多了。
我在設(shè)計(jì)和實(shí)踐低代碼/零代碼搭建平臺(tái) Dooring 的過程中,也遇到了多語言方案的技術(shù)選型,目前方案基本完成,接下來我將帶大家一步步分析多語言在不同技術(shù)棧中的實(shí)現(xiàn)方案,并以實(shí)際的項(xiàng)目讓大家掌握多言語技術(shù),在文章最后我也會(huì)提出對(duì)多語言未來演進(jìn)的一些方向,供大家研究和探索。
按照我一向的寫作風(fēng)格,我會(huì)在下面列出文章的大綱,以便大家有選擇且高效率的閱讀和學(xué)習(xí):
目前常用的多語言方案介紹和實(shí)踐
目前常用的多語言方案基本都是人工翻譯,然后通過動(dòng)態(tài)替換來實(shí)現(xiàn)語言的切換,但是不同的技術(shù)框架模式稍有不同, 接下來我們就逐個(gè)分析一下。
1. 原生js/jquery方案實(shí)現(xiàn)多語言
在傳統(tǒng)方案中最容易想到的就是dom替換。我們通過提前定義好多語言文件(或文案Map),并在html標(biāo)簽中做語言映射,最后通過切換函數(shù)來動(dòng)態(tài)的切換網(wǎng)站語言。其基本的模式如下:
js 體驗(yàn)AI代碼助手 代碼解讀復(fù)制代碼// 語言庫,我們有兩種方式來定義
// 1. 單文件Map模式, lang.js
const lang = {
zh: {
'title': 'H5編輯器',
'userLogin': '用戶登錄',
'usernameError': '請(qǐng)輸入用戶名'
},
en: {
'title': 'H5 editor',
'userLogin': 'The user logs on',
'usernameError': 'Please enter your username'
},
}
// 2. 多語言包模式
lang/cn.json
lang/en.json
html標(biāo)簽結(jié)構(gòu)如下:
<select id="langControl">
<option value="cn">中文</option>
<option value="en">English</option>
</select>
<div lang="title">H5編輯器</div>
<div lang="userLogin">用戶登錄</div>
最后我們通過 javascript 遍歷 [lang] 屬性并通過映射關(guān)系來替換語言。當(dāng)然我們還可以通過 template.js 這樣的模版引擎來優(yōu)化我們dom的渲染替換方式,但是以上方案在落地過程中仍然需要考慮很多問題。如下:
語言持久化需要單獨(dú)處理
無法動(dòng)態(tài)添加語言文本
無法引入變量以及讀取語言文本
缺乏靈活性和配置化
在傳統(tǒng)方案中我們?yōu)榱私鉀Q以上問題并支持更復(fù)雜系統(tǒng),我們不得不考慮插件化,當(dāng)然 Jquery-I18n 就是一個(gè)非常不錯(cuò)的解決方案。它可以幫助我們輕松地國際化 Web 應(yīng)用程序,并且支持鏈?zhǔn)秸{(diào)用, 且可以無刷新切換語言。接下來我就帶大家使用 Jquery-I18n 實(shí)現(xiàn)一個(gè)簡單的demo,讓大家更好的掌握該方案。
1.引入資源
<script src="https://cdn.bootcss.com/jquery/3.10.2/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/js-cookie/latest/js.cookie.min.js"></script>
<script src="./js/jquery.i18n.js"></script>
2.創(chuàng)建并配置多語言文件


3.編寫頁面內(nèi)容
<select id="langControl">
<option value="cn">中文</option>
<option value="en">English</option>
</select>
<div lang="title">H5編輯器</div>
<div lang="userLogin">用戶登錄</div>
4.初始化 i18n 配置并實(shí)現(xiàn)語言切換邏輯
function toggleLang(lang){
$("[lang]").i18n({
defaultLang: lang, // 默認(rèn)語言
filePath: "/lang/", // 語言文件所在的目錄
filePrefix: "", // 語言文件前綴
fileSuffix: "", // 語言文件后綴
forever: true,
callback: function(res) {} // 初始化后的回調(diào)
});
}
// 語言切換
$('#langControl').change(val => {
toggleLang(val)
}
當(dāng)然 Jquery-I18n 有更多強(qiáng)大的配置,大家可以參考文檔進(jìn)行配置,相關(guān)庫 github 地址如下:
Jquery-I18n
jquery-i18n-properties
當(dāng)然以上方案還只是手動(dòng)切換語言,更多的需求場景是要我們基于用戶當(dāng)前的瀏覽器環(huán)境或者網(wǎng)站鏈接地址的參數(shù)不同來自動(dòng)切換對(duì)應(yīng)的語言。對(duì)于通過鏈接參數(shù)來改變系統(tǒng)語言,這個(gè)我們只需要通過解析參數(shù)并進(jìn)行對(duì)應(yīng)的處理即可,比如解析 http://xxx.xxx?lan=cn 或 http://xxx.xxx?lan=en。當(dāng)然瀏覽器也提供了對(duì)應(yīng)的 api 可以獲取當(dāng)前用戶瀏覽的環(huán)境:navigator.language ,我們?cè)跒g覽器控制臺(tái)輸入該腳本的結(jié)果如下:
所以我們可以根據(jù)這個(gè)信息來自動(dòng)匹配用戶當(dāng)前的語言模式。
2. vue項(xiàng)目中的多語言方案
基于 Vue 的多語言方案網(wǎng)上也有很多,畢竟國內(nèi)大部分企業(yè)都在使用 Vue 開發(fā)項(xiàng)目,所以我簡單列舉幾個(gè)成熟的方案給大家,并對(duì)其中一個(gè)方案給出具體的實(shí)踐:
當(dāng)然大家如果做的不是很復(fù)雜的項(xiàng)目,也可以直接采用 simplest-i18n,因?yàn)槠涓唵屋p量。
接下來我會(huì)以一個(gè)完整的例子來說明如何使用 vue-i18n 來做 Vue 項(xiàng)目的國際化。
1.定義語言文件

2.引入依賴并注冊(cè)語言包
import Vue from "vue";
import VueI18n from "vue-i18n";
Vue.use(VueI18n);
// 加載所有語言環(huán)境并記住上下文
function loadMessages() {
const context = require.context("./lang", true, /[a-z0-9-_]+.json$/i);
const messages = context
.keys()
.map((key) => ({ key, locale: key.match(/[a-z0-9-_]+/i)[0] }))
.reduce(
(messages, { key, locale }) => ({
...messages,
[locale]: context(key),
}),
{}
);
return { context, messages };
}
const { context, messages } = loadMessages();
// VueI18n 實(shí)例
const i18n = new VueI18n({
locale: navigator.language, // 根據(jù)瀏覽器環(huán)境設(shè)置網(wǎng)站語言
messages,
});
// 運(yùn)行程序
const app = new Vue({
i18n,
// ...
}).$mount('#app');
// 切換語言(在組件內(nèi)也可以使用$i18n.locale來切換語言環(huán)境)
i18n.locale = 'en-US'
// 熱更新支持
if (module.hot) {
module.hot.accept(context.id, () => {
const { messages: newMessages } = loadMessages();
Object.keys(newMessages)
.filter((locale) => messages[locale] !== newMessages[locale])
.forEach((locale) => {
messages[locale] = newMessages[locale];
i18n.setLocaleMessage(locale, messages[locale]);
});
});
}
當(dāng)然在項(xiàng)目中我們還可以延遲加載翻譯,原理類似 webpack 的異步加載文件,參考如下:
export function loadLangAsync(lang) {
// 如果語言相同
if (i18n.locale === lang) {
return Promise.resolve(...)
}
// 如果語言已經(jīng)加載
if (loadedLanguages.includes(lang)) {
return Promise.resolve(...)
}
// 如果尚未加載語言
return import(/* webpackChunkName: "lang-[request]" */ `@/lang/${lang}.json`).then(
messages => {
// ... 處理邏輯
}
)
}
同時(shí) vue-cli 還提供了對(duì)應(yīng)的插件 vue-cli-plugin-i18n 來支持通過配置化的方式開啟多語言。
轉(zhuǎn)載:如何解決前端多語言選型和實(shí)現(xiàn)難題?多語言(i18n)支持 是企業(yè)項(xiàng)目走向國際化的必經(jīng)之路,也是前端工程師最佳實(shí)踐的內(nèi)容之 - 掘金