如何使用vue-i18n动态切换Locale?
问题
根据vue-i18n官方文档,初始化时可指定Locale,代码如下:
const i18n = createI18n({ locale: 'ja', fallbackLocale: 'en', messages: { en: { message: { hello: 'hello world' } }, ja: { message: { hello: 'こんにちは、世界' } } } })
随后将其挂载到Vue应用:
const app = createApp(Vue) app.use(i18n) app.mount('#app')
为实现Locale动态切换,将当前Locale存储在状态管理中:
const appStore = useAppStore() const i18n = createI18n({ locale: appStore.locale, // 更多代码... }) app.use(i18n)
但该方式不具备响应性:当状态管理中的Locale变更时,i18n对象不会更新,Locale未真正切换,组件也不会重渲染:
const appStore = useAppStore() appStore.locale='en' // 几乎无效果,组件未重渲染
发现i18n对象本身没有切换Locale的方法,即便监听Locale变更,也不知如何重新配置已运行的应用以使用新Locale,或者如何通过编程方式强制组件重渲染。请问该如何解决?
解决方案
核心原因
默认情况下vue-i18n使用Legacy模式,该模式下的locale不是响应式变量,无法直接通过状态变更触发更新。必须开启Composition API模式才能实现响应式的语言切换。
步骤1:修改i18n初始化配置
开启Composition API模式,同时开启全局注入方便组件使用:
const appStore = useAppStore() const i18n = createI18n({ legacy: false, // 必须设置为false,启用Composition API模式 globalInjection: true, // 全局注入$t、$i18n等方法 locale: appStore.locale, fallbackLocale: 'en', messages: { en: { message: { hello: 'hello world' } }, ja: { message: { hello: 'こんにちは、世界' } } } }) const app = createApp(Vue) app.use(i18n) app.mount('#app')
步骤2:联动状态管理与i18n
在状态管理中添加更新locale的方法,同步修改i18n的响应式locale:
// 以Pinia状态管理为例 import { defineStore } from 'pinia' // 引入初始化好的i18n实例 import { i18n } from '@/path/to/your/i18n-config' export const useAppStore = defineStore('app', { state: () => ({ locale: 'ja' // 初始语言 }), actions: { setLocale(newLocale) { this.locale = newLocale // 同步更新i18n的响应式locale i18n.global.locale.value = newLocale } } })
步骤3:组件内使用与切换
在组件中调用状态管理的方法即可触发语言切换,组件会自动响应重渲染:
import { useAppStore } from '@/stores/app' const appStore = useAppStore() // 切换到英文 const switchToEn = () => { appStore.setLocale('en') } // 切换到日文 const switchToJa = () => { appStore.setLocale('ja') }
备选方案:直接在组件中监听状态变化
如果不想在状态管理中耦合i18n,可以在组件内通过watch监听状态变化,同步更新i18n的locale:
import { useAppStore } from '@/stores/app' import { useI18n } from 'vue-i18n' import { watch } from 'vue' const appStore = useAppStore() const { locale } = useI18n() // 监听状态管理中的locale变化,同步到i18n watch( () => appStore.locale, (newLocale) => { locale.value = newLocale }, { immediate: true } // 初始化时同步一次 )
内容的提问来源于stack exchange,提问作者nagylzs
相关产品推荐
相关产品推荐

