在 vue-i18n 的子组件中使用基于组件的翻译
Use component based translations in child components in vue-i18n
我正在使用 vue-i18n 翻译我的 vue 应用程序中的消息。我在 new VueI18n(...)
中添加了一些全局翻译,在名为 c-parent
的组件中添加了一些基于组件的翻译。该组件包含名为 c-child
的子组件。现在,我想在 c-child
.
中也使用 c-parent
的基于组件的翻译
我在这个fiddle中做了一个小例子:https://jsfiddle.net/d80o7mpL/
问题出在输出的最后一行:c-child
中的消息未使用 c-parent
的基于组件的翻译进行翻译。
由于所有组件都"inherited" 进行全局翻译,因此我希望基于组件的翻译(在它们各自的组件子树中)也是如此。有没有办法在 vue-i18n 中实现这个?
嗯,您需要使用 props 将文本传递给子组件。
全球翻译由所有组件"inherited"。但是您在儿童中使用本地翻译。
const globalMessages = {
en: { global: { title: 'Vue i18n: usage of component based translations' } }
}
const componentLocalMessages = {
en: { local: {
title: "I\'m a translated title",
text: "I\'m a translated text"
}}
}
Vue.component('c-parent', {
i18n: {
messages: componentLocalMessages
},
template: `
<div>
<div>c-parent component based translation: {{ $t('local.title') }}</div>
<c-child :text="$t('local.title')"></c-child>
</div>
`
})
Vue.component('c-child', {
props: ['text'],
template: `
<div>c-child translation: {{ text }}</div>
`
})
Vue.component('app', {
template: '<c-parent />'
})
const i18n = new VueI18n({
locale: 'en',
messages: globalMessages
})
new Vue({
i18n,
el: "#app",
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
}
h5 {
margin: 1em 0 .5em 0;
}
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vue-i18n"></script>
<div id="app">
<h2>{{ $t('global.title') }}</h2>
We define two Vue components: <code><c-child/></code> contained in <code><c-parent/></code>.
<code><c-parent/></code> defines some component based translations. We would like to use the
parent's translations in the child but it does not work.
<h5>Example:</h5>
<app />
</div>
我正在做的是在 router.ts
中使用 i18n.mergeLocaleMessage 来 合并特定的 .i18n.json
翻译文件(通过设置 meta.i18n
属性) 对于 每条路线 :
const router = new Router({
[...]
{
path: '/settings',
name: 'settings',
component: () => import('./views/Settings.vue'),
meta: {
i18n: require('./views/Settings.i18n.json'),
},
},
[...]
});
router.beforeEach((to, from, next) => {
// load view-scoped translations?
if (!!to.meta.i18n) {
Object.keys(to.meta.i18n).forEach((lang) => i18n.mergeLocaleMessage(lang, to.meta.i18n[lang]));
}
next();
});
与 Settings.i18n.json
类似:
{
"en":
{
"Key": "Key"
},
"es":
{
"Key": "Clave"
}
}
这样,所有子组件将使用相同的翻译文件。
如果你不能使用 vue-router,也许你可以在父组件的 mounted() 钩子中完成(没试过)
我和 i18n 的情况一样。
假设我们有一个“卡片”对象道具,它包含我们将在将作为父级的 CardModal.vue 组件中使用的所需语言(我的情况)。
所以我所做的是获取所需的语言环境 json 文件(基于道具语言)并将这些消息添加到卡片道具中。
所以在父组件中我们将有:
<template>
<div id="card-modal">
<h1> {{ card.locales.title }} </h1>
<ChildComponent card="card" />
</div>
</template>
<script>
export default {
name: 'CardModal',
props: {
card: {
type: Object,
required: true,
}
}
data() {
return {
locale: this.card.language, //'en' or 'es'
i18n: {
en: require('@/locales/en'),
es: require('@/locales/es'),
},
}
},
created() {
this.card.locales = this.i18n[this.locale].card_modal
}
}
</script>
请注意,我们不再依赖插件函数 ( $t() ),我们只是更改当前组件中的语言环境。我这样做是因为我不想在每个子组件中使用“i18n”标签,并且希望将所有语言环境消息保存在每种语言的一个 json 文件中。我已经在所有子组件中使用了 card 道具,所以这就是我将语言环境添加到该对象的原因。
如果您需要在组件中使用 select 标记来更改语言环境,我们可以使用语言环境数据 属性 的观察器,例如 docs shows
我正在使用 vue-i18n 翻译我的 vue 应用程序中的消息。我在 new VueI18n(...)
中添加了一些全局翻译,在名为 c-parent
的组件中添加了一些基于组件的翻译。该组件包含名为 c-child
的子组件。现在,我想在 c-child
.
c-parent
的基于组件的翻译
我在这个fiddle中做了一个小例子:https://jsfiddle.net/d80o7mpL/
问题出在输出的最后一行:c-child
中的消息未使用 c-parent
的基于组件的翻译进行翻译。
由于所有组件都"inherited" 进行全局翻译,因此我希望基于组件的翻译(在它们各自的组件子树中)也是如此。有没有办法在 vue-i18n 中实现这个?
嗯,您需要使用 props 将文本传递给子组件。
全球翻译由所有组件"inherited"。但是您在儿童中使用本地翻译。
const globalMessages = {
en: { global: { title: 'Vue i18n: usage of component based translations' } }
}
const componentLocalMessages = {
en: { local: {
title: "I\'m a translated title",
text: "I\'m a translated text"
}}
}
Vue.component('c-parent', {
i18n: {
messages: componentLocalMessages
},
template: `
<div>
<div>c-parent component based translation: {{ $t('local.title') }}</div>
<c-child :text="$t('local.title')"></c-child>
</div>
`
})
Vue.component('c-child', {
props: ['text'],
template: `
<div>c-child translation: {{ text }}</div>
`
})
Vue.component('app', {
template: '<c-parent />'
})
const i18n = new VueI18n({
locale: 'en',
messages: globalMessages
})
new Vue({
i18n,
el: "#app",
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
}
h5 {
margin: 1em 0 .5em 0;
}
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/vue-i18n"></script>
<div id="app">
<h2>{{ $t('global.title') }}</h2>
We define two Vue components: <code><c-child/></code> contained in <code><c-parent/></code>.
<code><c-parent/></code> defines some component based translations. We would like to use the
parent's translations in the child but it does not work.
<h5>Example:</h5>
<app />
</div>
我正在做的是在 router.ts
中使用 i18n.mergeLocaleMessage 来 合并特定的 .i18n.json
翻译文件(通过设置 meta.i18n
属性) 对于 每条路线 :
const router = new Router({
[...]
{
path: '/settings',
name: 'settings',
component: () => import('./views/Settings.vue'),
meta: {
i18n: require('./views/Settings.i18n.json'),
},
},
[...]
});
router.beforeEach((to, from, next) => {
// load view-scoped translations?
if (!!to.meta.i18n) {
Object.keys(to.meta.i18n).forEach((lang) => i18n.mergeLocaleMessage(lang, to.meta.i18n[lang]));
}
next();
});
与 Settings.i18n.json
类似:
{
"en":
{
"Key": "Key"
},
"es":
{
"Key": "Clave"
}
}
这样,所有子组件将使用相同的翻译文件。
如果你不能使用 vue-router,也许你可以在父组件的 mounted() 钩子中完成(没试过)
我和 i18n 的情况一样。
假设我们有一个“卡片”对象道具,它包含我们将在将作为父级的 CardModal.vue 组件中使用的所需语言(我的情况)。 所以我所做的是获取所需的语言环境 json 文件(基于道具语言)并将这些消息添加到卡片道具中。
所以在父组件中我们将有:
<template>
<div id="card-modal">
<h1> {{ card.locales.title }} </h1>
<ChildComponent card="card" />
</div>
</template>
<script>
export default {
name: 'CardModal',
props: {
card: {
type: Object,
required: true,
}
}
data() {
return {
locale: this.card.language, //'en' or 'es'
i18n: {
en: require('@/locales/en'),
es: require('@/locales/es'),
},
}
},
created() {
this.card.locales = this.i18n[this.locale].card_modal
}
}
</script>
请注意,我们不再依赖插件函数 ( $t() ),我们只是更改当前组件中的语言环境。我这样做是因为我不想在每个子组件中使用“i18n”标签,并且希望将所有语言环境消息保存在每种语言的一个 json 文件中。我已经在所有子组件中使用了 card 道具,所以这就是我将语言环境添加到该对象的原因。
如果您需要在组件中使用 select 标记来更改语言环境,我们可以使用语言环境数据 属性 的观察器,例如 docs shows