I have following project structure (index.vue
):
<template>
<div class="container">
<navbar></navbar>
<social-media-bar></social-media-bar>
<main>
<home></home>
<news></news>
<vision></vision>
<event-section></event-section>
<artwork></artwork>
<about></about>
<donate></donate>
<contact></contact>
<partners></partners>
</main>
<footer-component></footer-component>
</div>
</template>
I want to change the app-language
from inside navbar.vue
:
<template>
<div class="nav-bar">
<fa class="icon-locale" @click="toggleLocale" :icon="[ 'fa', 'language' ]" size="2x"></fa>
<div class="locale-menu" :class="{ locale__open: isActiveLocale }">
<p @click="toggleLocale(); setLocale('en');">en</p>
<p @click="toggleLocale(); setLocale('de');">de</p>
<p @click="toggleLocale(); setLocale('ar');">ar</p>
</div>
</div>
</template>
<script setup>
import {ref} from "vue";
import {createI18n} from 'vue-i18n';
const isActiveLocale = ref(false);
const toggleLocale = () => {
isActiveLocale.value = !isActiveLocale.value;
}
const i18n = createI18n({});
const setLocale = (locale) => {
i18n.global.locale = locale
};
</script>
Basically this opens a locale menu
with en, de, ar
locales which start an @click
event that changes i18n.global.locale
accordingly.
I need to set the newly set i18n.global.locale
in the home
component.
home.vue
:
<template>
<section id="home" class="home">
<h2>{{ state.heading[state.locale] }}</h2>
</section>
</template>
<script setup>
import {reactive} from 'vue';
import {useI18n} from 'vue-i18n';
const {locale} = useI18n()
const loc = locale.value.substring(0, 2)
const state = reactive({
locale: loc
})
</script>
What I want is to get the newly set i18n.global.locale
from navbar.vue
into state.locale
in home.vue
reactively. Since navbar
and home
are no parent/child
, do I have to build an EventBus
for this or is there a more elegant solution, maybe with the i18n
library?
Edit:
This is the function, that is supposed to change locale
globally but it only sets it inside i18n
and it looks like the only reactivity possible with that is with i18n
's messages
, which I am not using.
const setLocale = () => {
i18n.global.locale = 'de'
console.log(i18n.global.locale);
};
I need to change the locale string globally, so that I can use it in all components reactively.
CodePudding user response:
i18n.js
import { createI18n } from "vue-i18n";
export const i18n = createI18n({
locale: "en",
messages: {
en: {
message: {
language: "Language",
hello: "hello world!"
}
},
ja: {
message: {
language: "言語",
hello: "こんにちは、世界!"
}
}
}
});
main.js
import { createApp } from "vue";
import App from "./App.vue";
import { i18n } from "./i18n";
createApp(App).use(i18n).mount("#app");
App.vue
<template>
<button @click="switch">switch to ja</button>
<p>{{ $t("message.hello") }}</p>
</template>
<script>
export default {
name: "App",
methods: {
switch() {
// $i18n is reactively
this.$i18n.locale = "ja";
},
},
};
</script>
CodePudding user response:
I found a super easy way to pass around variables between components in vue
with sessionStorage
. Just define:
sessionStorage.whatever = 'whateverYouWant'
and you can use sessionStorage.whatever
in all your components. Other than localStorage
, sessionStorage
will reset, when the browser/tab is closed.
I am using it to pass around the selected locale
.