Vue3 useI18n报错Must be called at top of setup function排查
问题原因
两个核心配置错误直接导致所有报错:
- i18n插件未正确注册:你将i18n实例作为第三个参数传入
app.use(VueAxios, axios, i18n),VueAxios不会代为注册i18n,等于i18n从未挂载到Vue应用实例上。这直接导致useI18n()执行时无法获取到注入的i18n上下文,抛出不在setup顶层的错误;globalInjection配置依赖插件注册流程生效,未注册时自然不存在$t方法,触发ctx.$t is not a function报错。 - setup返回值语法错误:App.vue的setup返回值中,你将
t包裹在额外的对象层内返回,实际导出的结构为{ ..., { t: 翻译函数 } },模板无法平级读取到t方法。 - 冗余无效代码:main.ts中默认导入的
Vue对象是Vue2的遗留写法,Vue3不存在该默认导出,属于无效代码。
修复方案
1. 修正入口文件main.ts
单独调用app.use(i18n)完成插件注册,移除无效的Vue默认导入,修正后代码:
// frontend/src/main.ts import i18n from './i18n'; import { createApp } from 'vue'; import axios from 'axios'; import VueAxios from 'vue-axios'; import App from './App.vue'; const app = createApp(App); // 单独注册i18n插件 app.use(i18n); app.use(VueAxios, axios); app.provide('axios', app.config.globalProperties.axios); app.mount('#i-english-editor');
2. 修正App.vue代码
调整setup返回值结构,将t与其他返回值平级导出即可,注意template标签需要有且仅有一个根节点:
<template> <div> {{ t('message.greeting') }} <!-- 开启globalInjection后也可直接使用$t写法,二选一即可 --> <!-- {{ $t('message.greeting') }} --> </div> </template> <script lang="ts"> import { defineComponent, ref, inject } from "vue"; import { useI18n } from "vue-i18n"; export default defineComponent({ setup() { const { t } = useI18n(); // 原有业务逻辑保持不变 return { // 原有返回的变量、方法保持不变 t, // 直接平级返回t,不要额外包裹对象 } } }); </script>
3. 补全翻译配置(可选)
你当前i18n配置的默认语言是ja(日文),但messages中未配置日文翻译词条,页面会直接显示key值。如果需要默认显示日文,在i18n.ts的messages中补充对应词条即可:
messages: { ja: { message: { language: "日本語", greeting: "こんにちは!" } }, en: { message: { language: "English", greeting: "Hello !" } }, ar: { message: { language: "العربية", greeting: "السلام عليكم" } }, es: { message: { language: "Español", greeting: "Hola !" } } }
修复完成后重启开发服务,所有控制台报错会消失,翻译功能正常生效。
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

