如何在Vue文件的JSON菜单中正确使用i18n实现多语言翻译?
解决Nuxt.js中JSON菜单的i18n翻译问题
你遇到的核心问题是:直接将t()的字符串形式写入菜单数据,并没有实际触发翻译函数执行。下面给出两种适配不同Nuxt版本的实用解决方案:
方法一:用计算属性动态生成带翻译的菜单(通用最优方案)
不管是Nuxt 2还是Nuxt 3,都可以通过计算属性处理原始菜单数据,把每个title替换为翻译后的内容。这种方式的优势是语言切换时,菜单文本会自动更新,无需手动重新渲染。
Nuxt 3(组合式API)示例
<script setup> import { useI18n, computed } from 'vue-i18n' const { t } = useI18n() // 原始菜单数据:存储翻译key而非硬编码文本 const rawMenus = [ { id: 1, titleKey: "main_menu", // 对应语言文件中的key submenus: [ { id: 1, titleKey: "home_1", url: "/" }, { id: 2, titleKey: "home_2", url: "/home-2" }, { id: 3, titleKey: "home_3", url: "/home-3" }, ], }, ] // 计算属性生成带翻译结果的菜单 const menus = computed(() => { return rawMenus.map(menu => ({ ...menu, title: t(menu.titleKey), submenus: menu.submenus.map(submenu => ({ ...submenu, title: t(submenu.titleKey) })) })) }) </script> <template> <!-- 直接渲染处理后的菜单即可 --> <nav> <ul> <li v-for="menu in menus" :key="menu.id"> {{ menu.title }} <ul v-if="menu.submenus"> <li v-for="submenu in menu.submenus" :key="submenu.id"> <a :href="submenu.url">{{ submenu.title }}</a> </li> </ul> </li> </ul> </nav> </template>
Nuxt 2(选项式API)示例
<script> export default { data() { return { rawMenus: [ { id: 1, titleKey: "main_menu", submenus: [ { id: 1, titleKey: "home_1", url: "/" }, { id: 2, titleKey: "home_2", url: "/home-2" }, { id: 3, titleKey: "home_3", url: "/home-3" }, ], }, ] } }, computed: { menus() { return this.rawMenus.map(menu => ({ ...menu, title: this.$t(menu.titleKey), submenus: menu.submenus.map(submenu => ({ ...submenu, title: this.$t(submenu.titleKey) })) })) } } } </script>
方法二:直接在菜单数据中调用翻译函数(仅组件内定义场景)
如果菜单是直接在组件内部定义的,也可以直接调用t()或$t()赋值title,但这种方式仅在组件初始化时执行一次,语言切换后需要手动触发菜单更新,不如计算属性灵活:
<script setup> import { useI18n } from 'vue-i18n' const { t } = useI18n() const menus = [ { id: 1, title: t("main_menu"), submenus: [ { id: 1, title: t("home_1"), url: "/" }, { id: 2, title: t("home_2"), url: "/home-2" }, { id: 3, title: t("home_3"), url: "/home-3" }, ], }, ] </script>
关键注意点
- 确保你的i18n语言文件中已经定义了对应的翻译key(比如
main_menu、home_1等) - 优先使用计算属性方案,它能自动响应语言切换,无需额外处理
- 绝对不要直接写字符串
"{t('xxx')}",这只是普通文本,不会被i18n解析
内容的提问来源于stack exchange,提问作者Artem
相关产品推荐
相关产品推荐

