I am working on a web application using the **Vue **and I am using vueI18n for internationalization. I have encountered an issue where the locale change is not immediately reflected in all components.
Here are the relevant details:
Application Details:
Problem Details:
I am using vueI18n in two components (MyHeader.vue
and HomeView.vue
). Here are the relevant code snippets:
MyHeader.vue
:
<div class="my-header">
<ul>
<router-link to="/">
<li
@mousedown="
home.click = true;
select('home');
"
@mouseup="home.click = false"
class="home"
:class="{ click: home.click, selected: home.selected }"
>
{{ $t("nav.home") }}
</li>
</router-link>
...
</div>
HomeView.vue
:
<div class="grid">
<img src="../assets/placeholder.jpg" :alt="$t('home.imgAlt')" />
<div class="profile">
<h2>{{ $t("home.profileH2") }}</h2>
<p>{{ $t("home.profileP1") }}</p>
<p>{{ $t("home.profileP2") }}</p>
</div>
...
</div>
In HomeView.vue
, I have a button that changes the value of this.$i18n.locale
when clicked:
<button><img @click="changeLocale()" :src="require(`../assets/${locale}.png`)"></button>
And the script for the button:
changeLocale() {
if (this.locale === "ES") {
this.locale = "EN";
this.$i18n.locale = "es";
} else {
this.locale = "ES";
this.$root.$i18n.locale = "en";
}
}
This is the i18n configuration in main.js
:
const app = createApp(App);
const i18n = createI18n({
locale: "en",
messages: {
en: require("./locales/en.json"),
es: require("./locales/es.json"),
},
});
app
.component("myHeader", myHeader)
.use(router)
.use(i18n)
.mount("#app");
The problem occurs when I click the button to change the locale. The locale changes, and therefore the language in HomeView.vue
changes according to what is specified in the JSON files for the locales. However, in the MyHeader.vue
component, the language of the links does not change until I click on each of them.
I tried changing the root locale through this.$root.$i18n.locale but it didn't work. I don't want to use a way to communicate the components, like Vuex, because as I understand i18n, I shouldn't have to. VueI18n should do it for me, right?
Thank you in advance!
So, while making a small reproducible code example I changed the method used to update the value of this.$i18n.locale
to a more compact version and it worked. I still don't know why it worked, but it did.
Previous method:
methods: {
changeLocale() {
if (this.locale === "ES") {
this.locale = "EN";
this.$i18n.locale = "es";
} else {
this.locale = "ES";
this.$root.$i18n.locale = "en";
}
}
},
Updated method:
methods: {
changeLocale() {
this.$i18n.locale = this.$i18n.locale === "en" ? "es" : "en";
if (this.$i18n.locale == "en")
this.locale = "ES";
else
this.locale = "EN";
}
},