在给Vue项目添加i18n支持(一)中我们介绍了如何给Vue项目添加国际化支持,但是在真实的项目中,将所有翻译写在一个文件中通常会带来一些问题,比如容易引起代码冲突,也不方便维护。
我们期望的i18n配置大概长这样,
1 2 3 4 5 6 7 8
| |--src/ | |--locales/ | | |--index.js | | |--app.js | | |--common.js | | |--module/ | | | |--sys-user.js | | | |--sys-role.js
|
app.js
用来存放与整个应用相关的一些翻译,比如应用标题,slogan等等。
common.js
用来存放公共翻译。
module
下则是各个模块单独的翻译。
各个模块的翻译配置可能是多层级的,例如公共翻译:
1 2 3 4 5 6 7 8 9 10 11 12 13
| export default { dialog: { delete: { title: { en: "Delete", zhcn: "删除" }, message: { en: "Deleted items cannot be retrieved, do you want to continue?", zhcn: "删除的条目将无法找回,是否继续?" }, yes: { en: "Delete", zhcn: "删除" }, no: { en: "Cancel", zhcn: "取消" } } } };
|
接下来我们来实现它。
locales
locales
目录下用来存放所有翻译配置,它最终导出的数据应该是这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| { _: { dialog: { delete: { message: { en: "", zhcn: ""} } } }, app: { name: { en: "", zhcn: "" } }, user: { username: { en: "", zhcn: "" } } }
|
像这个示例中的一样。
.env
在.env中定义语言列表
vue-i18n
我们需要在引入vue-i18n
的地方将上面的数据结构进行转换,转换的结果符合vue-i18n的预期。
i18n.js
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 27 28 29 30 31 32 33 34 35
| import Vue from "vue"; import VueI18n from "vue-i18n"; import i18nConf from "@/locales";
Vue.use(VueI18n);
const langs = process.env.VUE_APP_LANGS.split(",");
function load(conf, lang, result) { for (let k in conf) { if ( langs.every(item => Object.prototype.hasOwnProperty.call(conf[k], item)) ) { result[k] = conf[k][lang]; } else { result[k] = {}; load(conf[k], lang, result[k]); } } }
function loadLocaleMessages() { const messages = {}; langs.forEach(lang => { messages[lang] = {}; load(i18nConf, lang, messages[lang]); }); return messages; }
export default new VueI18n({ locale: process.env.VUE_APP_I18N_LOCALE || "en", fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || "en", messages: loadLocaleMessages() });
|
main.js
引入就好了
1 2 3 4 5 6 7 8
| import i18n from "./i18n";
new Vue({ router, store, i18n, render: h => h(App) }).$mount("#app");
|