9

我正在使用vue-i18n进行本地化。当我想翻译输入占位符时,如:

<input type="text" v-model="someValue" :placeholder="$t('translation.string')">

我必须使用$t()在每次重新渲染时执行的函数(库文档也提到)。这在我的简单预订表单中添加了数千个不必要的函数调用,我想避免这种情况。

有没有办法只绑定一次属性?翻译后的值在 Vue 实例的整个生命周期中不会改变。v-once不是我想要的,因为我想保持组件/节点的反应性,并且只对属性进行“硬编码”。

我知道我可以通过简单地将翻译后的字符串存储在数据对象中来实现我所需要的,但我想知道是否有替代的、更简单的解决方案(不需要大量的代码重复)。

4

1 回答 1

2

computed属性将执行您要查找的操作,因为它们仅在其依赖项更改时才会触发重新运行。由于this.$t('LOCALE.STRING')除非您的语言环境发生更改,否则不会更改,因此保证您只运行一次,之后该值将由 Vue 缓存以供后续渲染。

<template>
  ...
  <input
    ...
    :placeholder="translatedPlaceholder"
  >
  ...
</template>

<script>
  ...
  computed: {
    translatedPlaceholder() {
      return $t('translation.string');
    },
  },
  ...
</script>

这个解决方案最棒的部分是,如果语言环境确实发生了变化,那么 Vue 确实会刷新计算属性,将其更新为正确的值。


如果您正在寻找更广泛的示例,我已经整理了一个交互式片段来帮助演示此语法。

该片段包括一个简单的本地化问候语,后跟一个<p>标签中的随机数,带有两个按钮。文本中的本地化字符串是从计算属性中提取的。

第一个按钮将生成一个新数字,导致<p>在 DOM 中重新渲染。
第二个按钮将切换语言环境,导致 Vue-i18n 刷新本地化字符串。

每当重新执行计算的本地化属性时,它都会记录到控制台。
我还将脚本设置为在 Vue 更新 DOM 时登录到控制台。

const messages = {
  en: {
    "greeting": 'Hello!',
  },
  es: {
    "greeting": '¡Hola!',
  },
};

new Vue({ 
  i18n: new VueI18n({
    locale: 'en',
    messages,
  }),
  data() {
    return {
      num: 1,
    }
  },
  computed: {
    localizedGreeting() {
      console.log('Computed executed');
      return this.$t('greeting');
    },
  },
  methods: {
    swapLocale() {
      this.$i18n.locale = (this.$i18n.locale == 'en' ? 'es' : 'en');
    },
    randomNum() {
      this.num = Math.floor(Math.random() * 10000);
    },
  },
  updated() {
    console.log('DOM updated');
  },
}).$mount('#app')
.as-console-wrapper {
  max-height: 120px !important;
}
<script src="https://unpkg.com/vue@2/dist/vue.min.js"></script>
<script src="https://unpkg.com/vue-i18n@8"></script>

<div id="app">
  <p>{{ `${localizedGreeting} #${num}` }}</p>
  <button @click="randomNum()">Re-render Greeting</button>
  <button @click="swapLocale">Swap Greeting Locale</button>
</div>

如您所见,重新渲染不会导致计算属性重新执行,但交换语言环境,这正是我们在这里寻找的。


最后一点——虽然从技术上讲,原始代码中的性能会受到影响,但由于您正在重新执行$t()调用,因此值得记住的是,实际的性能影响可能很小。不要用简单来换取性能提升,除非它真的很有意义。

请记住,过早的优化是万恶之源

于 2021-05-21T17:54:01.387 回答