2👍
You are not setting the i18n locale when you try to switch the language in your setNewLanguage
function. You only update localStorage, but localStorage is not reactive.
You should import i18n in your Pinia store:
import { i18n } from './utils/i18n.js';
And set the global locale in your setNewLanguage
function:
i18n.locale = ‘es’;
See i18n docs: https://vue-i18n.intlify.dev/guide/essentials/scope.html#locale-changing
1👍
Saving the current locale in the Pinia store is not required to change the language. I18n and Quasar itself store necessary data.
However, locale storage comes in handy after reloading the page. You will be able to restore the last state at app startup.
Quasar uses standard names for locales of its internal components and system (en-GB
instead of en
). For example, q-table
is expected to show No result
according to the current language. I strongly recommend you use names instead of short ones to preserve the harmony.
Implementation
First rename src/locales/en.json
to src/locales/en-GB.json
, and also, src/locales/zh.json
to src/locales/zh-CN.json
.
Changing the locale will be easy if you use the names. To exercise, your code can be something like this:
<template>
<q-btn color="secondary" :label="$t('changeLanguage')">
<q-menu auto-close>
<q-list style="min-width: 100px">
<q-item v-for="(language, index) in languages" @click="changeLanguage(index)" clickable>
<q-item-section>{{ language }}</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</template>
<script setup>
// Importar internos de vue
import { ref } from 'vue';
import { useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n';
const $q = useQuasar();
const i18n = useI18n({useScope: 'global'});
import deQ from 'quasar/lang/de';
import enQ from 'quasar/lang/en-GB';
import esQ from 'quasar/lang/es';
import jaQ from 'quasar/lang/ja';
import ptQ from 'quasar/lang/pt';
import ruQ from 'quasar/lang/ru';
import zhQ from 'quasar/lang/zh-CN';
const langPacks = {
de: deQ,
'en-GB': enQ,
es: esQ,
ja: jaQ,
pt: ptQ,
ru: ruQ,
'zh-CN': zhQ,
};
// Constantes y variables del componente
const languages = ref({
'de': '🇩🇪 Deutsch',
'en-GB': '🇬🇧 English',
'es': '🇪🇸 Español',
'ja': '🇯🇵 日本語',
'pt': '🇵🇹 Português',
'ru': '🇷🇺 Русский',
'zh-CN': '🇨🇳 中文',
});
// Funciones y métodos
function changeLanguage(newLanguage) {
i18n.locale.value = newLanguage;
$q.lang.set(langPacks[newLanguage]);
localStorage.setItem('language', newLanguage);
}
</script>
Note 1:
In this case, there is no need for the Pinia store anymore. You can remove it safely. If you need to detect the current locale, you can use $q.lang.isoName
.
Using composition
Add a new composition file to manage the state and provides the necessary actions to change and restore locales.
// src/composable/use-locale-switcher.js
import { ref } from 'vue';
import { useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n';
import deQ from 'quasar/lang/de';
import enQ from 'quasar/lang/en-GB';
import esQ from 'quasar/lang/es';
import jaQ from 'quasar/lang/ja';
import ptQ from 'quasar/lang/pt';
import ruQ from 'quasar/lang/ru';
import zhQ from 'quasar/lang/zh-CN';
const langPacks = {
de: deQ,
'en-GB': enQ,
es: esQ,
ja: jaQ,
pt: ptQ,
ru: ruQ,
'zh-CN': zhQ,
};
export function useLocaleSwitcher() {
const locale = ref('es');
const $q = useQuasar();
const i18n = useI18n({useScope: 'global'});
function setLocale(lang) {
locale.value = lang;
i18n.locale.value = lang;
$q.lang.set(langPacks[lang]);
localStorage.setItem('language', lang);
}
function loadLastState(name) {
const prevState = localStorage.getItem('language');
setLocale(prevState || 'es');
}
return {
locale,
setLocale,
loadLastState,
};
}
Your lang switcher will be:
// src/components/ChangeLanguage
<template>
<q-btn color="secondary" :label="$t('changeLanguage')">
<q-menu auto-close>
<q-list style="min-width: 100px">
<q-item v-for="(language, index) in languages" @click="changeLanguage(index)" clickable>
<q-item-section>{{ language }}</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</template>
<script setup>
// Importar internos de vue
import { ref } from 'vue';
import { useLocaleSwitcher } from '../composable/use-locale-switcher.js';
const localeSwitcher = useLocaleSwitcher();
// Constantes y variables del componente
const languages = ref({
'de': '🇩🇪 Deutsch',
'en-GB': '🇬🇧 English',
'es': '🇪🇸 Español',
'ja': '🇯🇵 日本語',
'pt': '🇵🇹 Português',
'ru': '🇷🇺 Русский',
'zh-CN': '🇨🇳 中文',
});
// Funciones y métodos
function changeLanguage(newLanguage) {
localeSwitcher.setLocale(newLanguage);
}
</script>
And tune the app main file to restore state:
// src/App.vue
<template>
<router-view/>
</template>
<script setup>
import { useLocaleSwitcher } from './composable/use-locale-switcher.js';
const localeSwitcher = useLocaleSwitcher();
localeSwitcher.loadLastState();
</script>
Further:
For more information please visit the documentation.