安装

1
2
3
4
5
6
$ vue add i18n
? The locale of project localization. (en)
? The fallback locale of project localization. (en)
? The directory where store localization messages of project. It's stored under
`src` directory. (locales)
? Enable locale messages in Single file components ? (y/N) y

安装完成后,生成对应的插件文件i18n.js, 以及在main.js中注册了i18n插件。

plugins/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
import Vue from "vue";
import VueI18n from "vue-i18n";
Vue.use(VueI18n);
function loadLocaleMessages() {
const locales = require.context(
"../locales",
true,
/[A-Za-z0-9-_,\s]+\.json$/i
);
const messages = {};
locales.keys().forEach(key => {
const matched = key.match(/([A-Za-z0-9-_]+)\./i);
if (matched && matched.length > 1) {
const locale = matched[1];
messages[locale] = locales(key);
}
});
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 "./plugins/i18n";
export default new Vue({
router,
store,
vuetify,
i18n,
render: h => h(App)
}).$mount("#app");

使用

翻译

locales/en.json

1
2
3
4
5
6
7
8
9
10
11
12
{
"_": {
"validate": {
"required": "The field is required."
}
},
"auth": {
"username": "Username",
"password": "Password",
"login": "Sign In"
}
}

locales/zhcn.json

1
2
3
4
5
6
7
8
9
10
11
12
{
"auth": {
"username": "用户名",
"password": "密码",
"login": "登录"
},
"_": {
"validate": {
"required": "必填项"
}
}
}

模板中使用

1
2
<v-text-field :label="$t('auth.password')"></v-text-field>
<v-btn>{{ $t("auth.login") }}</v-btn>

组件中使用

1
this.$t("common.help")

改变locale

1
this.$i18n.locale = "zhcn"

集成Vuetify的翻译

locales/en.json

1
2
3
4
"$vuetify": {
"badge": "Badge",
"close": "Close"
}

Vuetify中的全部翻译项在node_modules/vuetify/es5/locale下可以找到。

然后再按如下修改vuetify插件。

plugins/vuetify.js

1
2
3
4
5
6
7
8
9
import Vue from "vue";
import Vuetify from "vuetify/lib/framework";
import i18n from "./i18n";
Vue.use(Vuetify);
export default new Vuetify({
lang: {
t: (key, ...params) => i18n.t(key, params)
}
});

常见问题

  • data方法中的数组在改变locale后不会更新

    例如:

    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
    <template>
    <v-menu left offset-y transition="slide-x-transition">
    <v-list dense min-width="48" nav width="140">
    <template v-for="(item, index) in actions">
    <v-list-item :key="item.name" link>
    <v-list-item-content>
    <v-list-item-title>{{ item.title }}</v-list-item-title>
    </v-list-item-content>
    </v-list-item>
    </template>
    </v-list>
    </v-menu>
    </template>
    <script>
    export default {
    data() {
    return {
    actions: [
    { icon: "mdi-help", name: "help", title: this.$t("common.help") },
    {
    icon: "mdi-account-box-outline",
    name: "settings",
    title: this.$t("common.settings")
    },
    {
    divider: true,
    icon: "mdi-logout",
    name: "sign_out",
    title: this.$t("auth.logout")
    }
    ]
    };
    }
    };
    </script>

解决方法:

  1. 添加到计算属性中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    computed: {
    actions: function() {
    return [
    { icon: "mdi-help", name: "help", title: this.$t("common.help") },
    {
    icon: "mdi-account-box-outline",
    name: "settings",
    title: this.$t("common.settings")
    },
    {
    divider: true,
    icon: "mdi-logout",
    name: "sign_out",
    title: this.$t("auth.logout")
    }
    ];
    }
    }
  1. 或者在模板中使用$t

    1
    2
    3
      <v-list-item-content>
    <v-list-item-title>{{ $t(item.title) }}</v-list-item-title>
    </v-list-item-content>

Reference