Vue3+Vite script setup使用vue-i18n提示i18n.global为undefined
问题排查与修复
你遇到的Uncaught TypeError: i18n.global is undefined错误由4个核心代码问题导致,按以下步骤修复即可:
- 函数调用漏传i18n实例,导致函数内部拿到的i18n值为undefined,访问global属性直接报错
- i18n.js内重复创建2次i18n实例,不同场景下引用的实例不一致
- legacy模式判断逻辑写反,legacy模式下i18n实例不存在global属性
- Vite配置缺失composition模式必要参数,动态导入语言包路径错误
第一步:重写i18n.js配置
统一单例i18n实例,修正逻辑错误和路径问题:
import { nextTick } from "vue"; import { createI18n } from "vue-i18n"; import axios from "axios"; import tr from "../src/locales/tr.json"; import en from "../src/locales/en.json"; export const SUPPORT_LOCALES = ["tr", "en"]; let i18nInstance = null; export function setupI18n(options = { locale: "tr" }) { i18nInstance = createI18n({ legacy: false, globalInjection: true, fallbackLocale: "tr", messages: { tr, en }, ...options }); setI18nLanguage(options.locale); return i18nInstance; } export function setI18nLanguage(locale) { if (!i18nInstance) throw new Error("请先调用setupI18n初始化i18n实例"); // 修正legacy判断:legacy模式无global属性,composition模式才挂载在global下 if (i18nInstance.mode === "legacy") { i18nInstance.locale = locale; } else { i18nInstance.global.locale.value = locale; } axios.defaults.headers.common["Accept-Language"] = locale; document.documentElement.setAttribute("lang", locale); } export async function loadLocaleMessages(locale) { if (!i18nInstance) throw new Error("请先调用setupI18n初始化i18n实例"); // 修正动态导入路径,和静态导入路径保持一致 const messages = await import(/* @vite-ignore */ `../src/locales/${locale}.json`); i18nInstance.global.setLocaleMessage(locale, messages.default); return nextTick(); } export default i18nInstance;
第二步:修正main.js挂载逻辑
确保全局只使用setupI18n创建的唯一实例:
import { createApp } from 'vue' import App from './App.vue' import { setupI18n } from './i18n.js' const app = createApp(App) app.use(setupI18n({ locale: 'tr' })) app.mount('#app')
第三步:修正组件内调用逻辑
补全函数调用参数,修正语言切换流程:
<script setup> import { ref, onBeforeMount } from 'vue' import { useI18n } from 'vue-i18n' import { SUPPORT_LOCALES, setI18nLanguage, loadLocaleMessages } from '../../i18n.js' const { locale } = useI18n() const currentLocale = ref(locale.value) async function selectLanguage(e) { const targetLocale = e.target.value await loadLocaleMessages(targetLocale) setI18nLanguage(targetLocale) currentLocale.value = targetLocale } onBeforeMount(() => { setI18nLanguage(currentLocale.value) }) </script>
第四步:修正vite.config.js配置
添加i18n插件必要配置,适配composition API模式:
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import vueI18n from '@intlify/vite-plugin-vue-i18n' import { fileURLToPath, URL } from 'node:url' export default defineConfig({ plugins: [ vue(), vueI18n({ include: [fileURLToPath(new URL('./src/locales/**', import.meta.url))], runtimeOnly: false // composition模式必须开启,否则会出现API未定义错误 }) ], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } } })
注意:如果你的locales文件夹实际路径和代码里写的不一致,要把导入路径改成你项目的真实路径,否则会出现语言包加载失败的问题。
内容的提问来源于stack exchange,提问作者Kayahan Kahrıman
相关产品推荐
相关产品推荐

