在 Vue 应用程序中动态更改语言环境不会更新页面上的翻译值
Posted
技术标签:
【中文标题】在 Vue 应用程序中动态更改语言环境不会更新页面上的翻译值【英文标题】:Changing locale dynamically in Vue app doesn't update translated values on pages 【发布时间】: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 我用更多细节更新了这个问题。 【参考方案1】:如果您指的是label: i18n.t(...)
,它只会运行一次。语言的任何变化都不会改变标签。一种解决方案是将文本键放在您的字段中,并在组件中对包含文本键的变量使用 $t:
field.js
...
const fields =
userId:
label: 'users.generalInfo.userId',
...
component
<v-text-field
:label="$t(fields.userId.label)"
/>
【讨论】:
以上是关于在 Vue 应用程序中动态更改语言环境不会更新页面上的翻译值的主要内容,如果未能解决你的问题,请参考以下文章