【发布时间】:2020-07-01 22:08:52
【问题描述】:
我有一个大型的 Vue 应用程序(使用 Vuetify),我最近将 vue-i18n 合并到其中。我的 json 翻译文件已设置并正常工作,我对 $t() 的调用在我的组件和其他 .js 文件中运行良好。但是,我一直无法做的是即时更改语言环境,以便我所有翻译字段中的文本都显示适当的语言。如果我更改我的 new Vue18n({}) 定义并保存文件,它可以正常工作,并且我的所有翻译值都可以正常显示。
在我的情况下,我可以选择菜单上的项目,
<v-icon color="primary" dark slot="activator">
person
</v-icon>
<v-list dark class="primary">
<v-list-tile>
<v-list-tile-title>{{ getUser.userId }}</v-list-tile-title>
</v-list-tile>
<v-divider />
<v-list-tile @click="passDialog = !passDialog">
<v-list-tile-title>Password</v-list-tile-title>
</v-list-tile>
<v-list-tile @click="logoutClick">
<v-list-tile-title>Logout</v-list-tile-title>
</v-list-tile>
<v-list-tile>
<v-list-tile-title @click="setLocale('en')">English</v-list-tile-title>
</v-list-tile>
<v-list-tile>
<v-list-tile-title @click="setLocale('es')">Spanish</v-list-tile-title>
</v-list-tile>
</v-list>
以及将适当的语言环境传递给方法的点击处理程序:
setLocale(locale) {
this.$root.$i18n.locale = locale;
},
这里定义了VueI18n:
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: 'en',
localeDir: 'locales',
fallbackLocale: 'en',
messages: loadLocaleMessages(),
});
我也尝试过变体,例如
this.$i18n.locale = locale;
和
i18n.locale = locale;
也做了之后
import i18n from `@/i18n';
在组件中。但是,几乎没有一个会更改我所有具有翻译的字段名称值。就好像我必须在语言更改后强制重新呈现我的翻译值。
在我选择了不同的语言后,我需要做些不同的事情来更新我的所有翻译值吗?
更新:根据下面 Romain Vincent 的评论,我意识到我错过了设置的一个重要部分。每个字段都有多个 Vuetify 属性,它们被提取到单独的fields.js 文件中。例如,以下是来自模板的几个字段定义:
<v-layout row>
<v-flex xs6>
<v-text-field
v-bind="fields.userId"
v-model="userModel.userId"
:disabled="!canSave"
/>
</v-flex>
<v-flex xs6>
<v-text-field v-bind="fields.id" v-model="userModel.id" disabled />
</v-flex>
</v-layout>
...
import { fields, buttons, csvFields } from '@/components/config/users';
...
data: () => ({
fields,
...
})
然后这里是fields.js:
import RuleGenerator from '@/utils/RuleGenerator';
import i18n from '@/i18n';
const fields = {
userId: {
label: i18n.t('users.generalInfo.userId'),
// Set label to 'Email' because the username is required to be an email address.
rules: new RuleGenerator('Email')
.setRequired()
.setMin(1)
.setMax(255)
// eslint-disable-next-line no-useless-escape
.setRegEx(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/)
.getRules(),
hint: 'Must be a valid email address',
counter: '255',
},
id: {
label: i18n.t('users.generalInfo.id'),
},
};
export default fields;
这些字段不会改变语言环境。但是,如果我直接在组件中绑定label:
<v-text-field
v-bind="fields.userId"
v-model="userModel.userId"
:disabled="!canSave"
:label="$t('users.generalInfo.userId')"
/>
更改语言环境可以很好地更新标签值。因此,即使它包含 i18n.js(这是设置 locale 的位置),也似乎存在该绑定文件的问题。
更新 2: 其他人似乎也遇到了这个问题 (see this GitHub issue)。
【问题讨论】:
-
我认为您还有另一个问题是阻止反应发生,因为据我所知,您用于更改语言环境的代码是正确的。我刚刚在控制台中使用 $vm.$i18n.locale = 'en'/'xxx' 进行了尝试,它可以立即运行
-
@RomainVincent 我用更多细节更新了这个问题。
标签: javascript vue.js localization vuetify.js vue-i18n