If you're seeking a solution where only a single run is guaranteed, using a computed
property is the way to go. Computed properties in Vue will trigger a re-run only when their dependencies change. Hence, with this.$t('LOCALE.STRING')
remaining constant unless the locale changes, Vue will cache the value for subsequent renders.
<template>
...
<input
...
:placeholder="translatedPlaceholder"
>
...
</template>
<script>
...
computed: {
translatedPlaceholder() {
return $t('translation.string');
},
},
...
</script>
An added benefit of this approach is that if the locale does change, Vue will refresh the computed property accordingly, ensuring the correct value is displayed.
I have created an interactive snippet to illustrate this syntax further, providing a more detailed example.
The snippet contains a basic localized greeting followed by a random number within a <p>
tag, along with two buttons. The localized string in the text is accessed through a computed property.
The first button generates a new number, triggering a re-render of the <p>
element in the DOM.
The second button switches the locale, prompting Vue-i18n to update the localized string.
Every execution of the computed localization property logs to the console.
I've also set up logging to the console whenever Vue updates the 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>
As demonstrated, re-rendering does not cause the computed property to re-execute, while changing the locale triggers it, aligning perfectly with our requirements.
Finally, it's worth noting that though there may be a slight performance impact in your initial code due to the recurring $t()
calls, the actual difference is likely minimal. Prioritize simplicity over optimizing for performance unless absolutely necessary.
Always remember, premature optimization is the root of all evil!