
在 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 模式,获得更好的类型支持与响应式控制能力。










