javascript - 如何只用 v-bind 绑定(bind)属性一次?

标签 javascript vue.js vuejs2 vue-i18n

我正在使用 vue-i18n用于本地化。当我想翻译输入占位符时,如:
<input type="text" v-model="someValue" :placeholder="$t('translation.string')">
我必须使用 $t()在每次重新渲染时执行的函数( library docs mention 也是如此)。这在我的简单预订表单中添加了数千个不必要的函数调用,我想避免这种情况。

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

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

最佳答案

一个 computed property会做你正在寻找的东西,因为它们只会在它们的依赖关系发生变化时触发重新运行。由于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()调用,值得记住的是,实际的性能影响可能很小。不要用简单来换取性能提升,除非它真的很有意义。
请记住, premature optimization is the root of all evil !

关于javascript - 如何只用 v-bind 绑定(bind)属性一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49053575/

相关文章:

javascript - 需要帮助在 firestore 中搜索值

javascript - 在作用域槽中传递 prop 不起作用

php - vue组件中的csrf token

vue.js - Vuetify 在数据表中插入操作按钮并获取行数据

javascript - 在 Javascript 上通过旋转跟随图像到鼠标

javascript - 如何为 AngularJS 表单编写通用错误处理程序

javascript - 单击缩略图时使用 JavaScript 更改大图像

ajax - 如何在 Vue 属性中传递 XMLHttpRequest responseText

javascript - Vue路由器工作不稳定

javascript - 检查 $_GET 数据是否在文档加载时被扔进页面