
在 vue 3 + vue-i18n(v9+)中,若初始化时设置 `legacy: false`(composition api 模式),则无法通过 `this.$i18n.locale = ‘xx’` 动态切换语言;必须启用 `legacy: true` 并配合 options api,或改用 composition api 的 `usei18n()` 响应式方式。
你遇到的问题根源在于 API 模式不匹配:vue-i18n v9 默认采用 Composition API(legacy: false),此时 $i18n 实例不再挂载到组件实例上(即 this.$i18n 为 undefined 或只读),直接赋值 this.$i18n.locale = … 不会触发响应式更新,甚至可能静默失败。
✅ 正确解法一:启用 Legacy 模式(兼容 Options API)
修改 i18n.js,将 legacy: false 改为 true:
// i18n.js import {createI18n} from 'vue-i18n'; import translations from '@/translation.js'; const i18n = createI18n({legacy: true, // ? 关键:启用 Options API 兼容模式 locale: 'de', // 建议设默认值(非空字符串),避免 fallback 触发异常 fallbackLocale: 'de', messages: translations // ⚠️ 注意:原代码中误写为 `translation`,应为 `messages`}); export default i18n;
并在 App.vue 的 Options API 中安全设置 locale(确保 this.$i18n 可用):
? 提示:locale: ” 是非法值,会导致内部 fallback 逻辑异常;务必设为有效 locale 字符串(如 ‘de’、’en’)。
✅ 正确解法二:纯 Composition API 方式(推荐新项目)
若坚持使用 legacy: false(现代写法),需在组件中通过 useI18n() 获取可响应式控制的实例:
立即学习 “ 前端免费学习笔记(深入)”;
同时确保 i18n.js 配置正确(注意 messages 键名):
// i18n.js const i18n = createI18n({legacy: false, locale: 'de', fallbackLocale: 'de', messages: translations // ✅ 修正字段名(非 translation)});
⚠️ 其他关键注意事项
- 字段名校验:createI18n 选项中必须使用 messages(不是 translation 或 translation),否则翻译资源不加载;
- Vuex getter 安全性:确保 store.getters[‘settings’].language 返回的是合法 locale 字符串(如 ‘en’, ‘fr’),避免空值或拼写错误;
- 动态加载语言包 :如需按需加载 多语言 ,建议结合 defineAsyncComponent 或 import() 实现 懒加载,避免初始包体积过大;
- 调试技巧:在控制台执行 app.config.globalProperties.$i18n?.locale(Legacy)或 i18n.locale.value(Composition)验证当前值。
综上,最快速修复是启用 legacy: true 并修正 messages 字段与默认 locale;长期建议迁移到 Composition API 模式,获得更好的类型支持与响应式控制能力。