在 Vue 中使用 i18n 做国际化

产品要走向国际,先把语言搞起来呀!Vue I18n 是 Vue.js 的国际化插件,非常好用!在此记录我的使用经验。

全局使用

涉及的主要文件如下,语言文件放在 locale 文件加下

├─src    
  ├─main.js 
  ├─locale
    ├─en.js
    ├─zh.js
    └─index.js

文件内容如下

./src/locale/index.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
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import en from './en'
import zh from './zh'

Vue.use(VueI18n)

const LOCALE_KEY = 'locale_language'
const DEFAULT_LANG = 'zh'

const localeLang = window.localStorage.getItem(LOCALE_KEY) || DEFAULT_LANG

const i18n = new VueI18n({
locale: localeLang,
fallbackLocale: DEFAULT_LANG,
messages: {
en,
zh
}
})

export {
DEFAULT_LANG,
localeLang
}

export default i18n
./src/locale/en.js
1
2
3
4
5
6
7
8
export default {
lang: 'English',
frame: {
home: 'home page'
...
}
...
}
./src/locale/zh.js
1
2
3
4
5
6
7
8
export default {
lang: '简体中文',
frame: {
home: '主页'
...
}
...
}
./src/main.js
1
2
3
4
5
6
7
import i18n from './locale'
...

new Vue({
i18n,
...
}).$mount('#app')

只需要使用一个表单绑定 v-model=”$i18n.locale” 就能实现动态更换应用语言了。

单文件内使用

上述的 en.js zh.js 都是全局先定义好的,在单个组件中可以在单独定义,优先级更高:

写在组件实例的 options 里

App.vue
1
2
3
4
5
6
7
8
9
10
11
12
export default {
data () {
...
},
i18n: {
messages: {
zh: { ... },
en: { ... }
}
}
...
}

写在 <i18n> 标签里,这需要安装 vue-i18n-loader,并且内容必须是一个 JSON。你可以使用 yml 替代 JSON ,前提是要再配置一个 yaml-loader

App.vue
1
2
3
4
5
6
7
8
9
10
<template>
...
</template>

<i18n>
{
"zh": { ... }
"en": { ... }
}
</i18n>

配置 vue-i18n-loader 依赖于 vue-loader ,vue-loader 版本 v15 以上的配置不一样,如下:

vue-loader version >= 15

1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
},
{
resourceQuery: /blockType=i18n/,
type: 'javascript/auto',
loader: '@kazupon/vue-i18n-loader'
}
...
]
...

vue-loader version <= 14

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
preLoaders: { // 如果你在 <i18n> 内使用 yml 替代 JSON
i18n: 'yaml-loader'
},
loaders: {
// you need to specify `i18n` loaders key with `vue-i18n-loader` (https://github.com/kazupon/vue-i18n-loader)
i18n: '@kazupon/vue-i18n-loader'
...
}
}
}
...
]
...

在单文件内同时使用上述两种方式时,只用第二种生效!

结合 element-ui

ElementUI 自己封装 t 函数用来解析多语言, 当使用 vue-i18n 时传入 i18n 函数, 会自动替换成 vue-i18n 的 t 函数

加载 ElementUI 时传入参数

main.js
1
2
3
4
5
...
import i18n from './locale'
import ElementUI from 'element-ui'
Vue.use(ElementUI, { i18n: (path, opt) => i18n.t(path, opt) })
...

zh.js en.js 要混入 ElementUI 的语言资源

./src/locale/zh.js
1
2
3
4
5
6
7
8
9
10
import enLocale from 'element-ui/lib/locale/lang/en'

export default {
lang: '简体中文',
frame: {
home: '主页'
...
}
...enLocale // 混入
}

结合 vux

vux 是比较老的 vue 组件库了, 使用了 vuex-i18n 插件做本地化

官方文档的介绍很少, 看了仓库源码才知道怎么配

  • 修改 vuxloader, 增加 plugins 配置项如下
1
2
3
4
5
6
7
{
name: 'i18n',
vuxStaticReplace: false,
staticReplace: false,
extractToFiles: 'src/locales/components.yml',
localeList: ['en', 'zh-CN']
}
  • webpack 配置 module.rules 添加 js-yaml-loader, 因为 vux 的语言文件使用的是 yml 语法
1
2
3
4
{
test: /\.(yaml|yml)$/,
loader: 'js-yaml-loader'
}
  • vuex 配置
1
2
3
4
5
6
7
8
9
10
11
import Vue from 'vue'
import Vuex from 'vuex'
import vuexI18n from 'vuex-i18n'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
// .. state, mutations, getters, actions, plugins, strict
i18n: vuexI18n.store
}
})
Vue.use(vuexI18n.plugin, store)
  • main.js 文件配置
1
2
3
4
5
6
7
8
9
10
11
12
13
import {zh, en}from './locale/lang'
import vuxLocales from 'vux/src/locales/all.yml'
import { LocalePlugin } from 'vux'
Vue.use(LocalePlugin)
const finalLocales = {
en: Object.assign(vuxLocales['en'], en),
zh: Object.assign(vuxLocales['zh-CN'], zh)
}
for (let i in finalLocales) {
Vue.i18n.add(i, finalLocales[i])
}
// 设置初始值
Vue.i18n.set('zh')
The End

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×