0

我正在使用vue-i18n在我的 vue 应用程序中翻译消息。我有一些添加的全局翻译new VueI18n(...)以及一个名为c-parent. 该组件包含名为 的子组件c-child。现在,我想使用基于组件的翻译c-parent也在c-child.

我在这个小提琴中做了一个小例子:https ://jsfiddle.net/d80o7mpL/

问题出在输出的最后一行: 中的消息c-child未使用基于组件的翻译进行翻译c-parent

由于所有组件都“继承”了全局翻译,因此我希望基于组件的翻译(在它们各自的组件子树中)也是如此。有没有办法在 vue-i18n 中实现这一点?

4

3 回答 3

1

那么,您需要使用道具将文本传递给子组件。

全局翻译由所有组件“继承”。但是您在孩子中使用本地翻译。

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>&lt;c-child/&gt;</code> contained in <code>&lt;c-parent/&gt;</code>.
  <code>&lt;c-parent/&gt;</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>

于 2019-03-28T14:29:09.760 回答
1

我正在做的是使用i18n.mergeLocaleMessage每条路线router.ts合并特定的.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()钩子里做(没试过)

于 2019-07-30T11:33:57.713 回答
0

我和 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 道具,所以这就是我将语言环境添加到该对象的原因。

如果您需要使用组件中的选择标记更改区域设置的方法,我们可以使用一个观察器来查看区域设置数据属性,如文档所示

于 2021-08-12T08:56:51.337 回答