在使用i18n和Pinia的Vue.js应用中更改语言时,如何更新翻译的文本?

mwkjh3gx  于 2023-05-23  发布在  Vue.js
关注(0)|答案(2)|浏览(344)

我正在使用i18 n和Pinia来尝试更改应用程序中的语言,但是当我更改语言时,只有localStorage.language的值发生了变化,但文本没有变化。我尝试使用pinia来“强制”重新渲染,但它也不起作用。我想知道如何做到这一点,因为尽管localStorage.language的值发生了变化,但应用程序不会重新呈现。
这是我的语言商店:

import { defineStore } from 'pinia'

export const useLanguageStore = defineStore('languages', {
  store: () => {
    return {
      language: 'es',
    }
  },
  actions: {
    setNewLanguage({ newLanguage } = {}) {
      if (!localStorage.language) {
        this.language = newLanguage ?? 'es'
        localStorage.setItem('language', this.language)
      }
    }
  },
})

这是i18n.js:

import { createI18n } from 'vue-i18n'
import messages from '@intlify/unplugin-vue-i18n/messages'

import pinia from '../stores'

export const i18n = createI18n({
  legacy: false,
  globalInjection: true,
  locale: localStorage.language,
  fallbackLocale: 'es',
  availableLocales: ['de', 'en', 'es', 'ja', 'pt', 'ru', 'zh'],
  messages: messages
});

这是我的main.js(如果有必要的话):

import { createApp } from 'vue'
import { Quasar } from 'quasar'
import quasarLang from 'quasar/lang/es'
import router from './routes/router.js'
import { createPinia, PiniaVuePlugin } from 'pinia'

// Import icon libraries
import '@quasar/extras/material-icons/material-icons.css'
import '@quasar/extras/material-icons-outlined/material-icons-outlined.css'
import '@quasar/extras/material-icons-round/material-icons-round.css'
import '@quasar/extras/material-icons-sharp/material-icons-sharp.css'

// A few examples for animations from Animate.css:
import '@quasar/extras/animate/fadeIn.css'
import '@quasar/extras/animate/fadeOut.css'

// Import Quasar css
import 'quasar/src/css/index.sass'

import { i18n } from './utils/i18n.js'

import App from './App.vue'

createApp(App)
.use(createPinia())
.use(Quasar, {
  plugins: {}, // import Quasar plugins and add here
  lang: quasarLang,
})
.use(router)
.use(i18n)
.mount('#app')

我已经将存储库公开以获取更多信息(显然,它有最新的更改);反正我还没有开始实际的开发,所以应该不会有问题:https://github.com/Santiago1010/idi-front

ryoqjall

ryoqjall1#

当您尝试在setNewLanguage函数中切换语言时,您没有设置i18n区域设置。您只更新localStorage,但localStorage不是响应式的。
您应该在您的Pinia商店中导入i18n:

import { i18n } from './utils/i18n.js';

然后在setNewLanguage函数中设置全局语言环境:

i18n.locale = ‘es’;

参见i18n文档:https://vue-i18n.intlify.dev/guide/essentials/scope.html#locale-changing

6vl6ewon

6vl6ewon2#

在Pinia存储区中保存当前区域设置并不需要更改语言。I18n和Quasar本身存储必要的数据。
但是,在重新加载页面后,区域设置存储就派上用场了。您将能够恢复应用程序启动时的最后状态。
Quasar使用standard names作为其内部组件和系统的语言环境(en-GB而不是en)。例如,q-table应该根据当前语言显示No result。我强烈建议你用名字而不是短的,以保持和谐。

实现

首先将src/locales/en.json重命名为src/locales/en-GB.json,然后将src/locales/zh.json重命名为src/locales/zh-CN.json
如果使用名称,更改区域设置将很容易。为了练习,你的代码可以是这样的:

<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>
注1:

在这种情况下,不再需要Pinia商店。您可以安全地删除它。如果您需要检测当前区域设置,可以使用$q.lang.isoName

使用合成

添加一个新的复合文件来管理状态,并提供更改和恢复区域设置所需的操作。

// 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,
  };
}

您的lang switcher将是:

// 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>

并调整应用程序主文件以恢复状态:

// src/App.vue
<template>
  <router-view/>
</template>

<script setup>
import { useLocaleSwitcher } from './composable/use-locale-switcher.js';

const localeSwitcher = useLocaleSwitcher();
localeSwitcher.loadLastState();
</script>
进一步:

有关更多信息,请访问the documentation

相关问题