菜单国际化:正确使用i18n国际化的3种姿势
菜单标题的国际化看起来简单——不就是 t('menu.home') 吗?但在 Vue 3 的 <script setup> 中,useI18n() 的使用方式有三种,每种都有适用场景和注意事项。选错方式可能导致菜单标题不随语言切换更新、或者在 SSR 环境下报错。
三种国际化姿势
姿势一:在组件中使用 useI18n
最标准的方式,在 Vue 组件的 <script setup> 中调用:
// 在组件内部
const { t } = useI18n()
const title = computed(() => t('menu.home'))
typescript
特点:响应式,语言切换时自动更新。但只能在 Vue 组件的 setup 上下文中使用。
姿势二:在 composable/工具函数中使用
在非组件文件(如 useMenu.ts)中无法直接使用 useI18n,需要通过全局 i18n 实例:
// src/utils/i18n.ts
import i18n from '@/i18n'
export function tt(key: string) {
return i18n.global.t(key)
}
typescript
在 composable 中使用:
import { tt } from '@/utils/i18n'
function generateMenuTitle(meta: RootMeta): string {
return meta.title ? tt(meta.title) : ''
}
typescript
特点:非响应式,适用于一次性数据转换。语言切换后需要重新调用才能获得新翻译。
姿势三:在路由 meta 中存储 i18n key
不在 meta.title 中存储翻译后的文本,而是存储 i18n key:
definePage({
meta: {
title: 'menu.home', // i18n key,而非 "首页"
},
})
typescript
在菜单渲染时动态翻译:
<template>
<span>{{ t(data.meta.title) }}</span>
</template>
vue
特点:响应式、数据与视图分离,推荐在大型项目中使用。
Element Plus 的国际化配置
Element Plus 组件默认使用英文。要与 vue-i18n 联动,需要在 App.vue 中配置 ElConfigProvider:
<template>
<ElConfigProvider :locale="elementLocale">
<RouterView />
</ElConfigProvider>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { ElConfigProvider } from 'element-plus'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import en from 'element-plus/es/locale/lang/en'
import { useI18n } from 'vue-i18n'
const { locale } = useI18n()
const elementLocale = computed(() => {
const lang = locale.value.toLowerCase()
return lang === 'zh-cn' ? zhCn : en
})
</script>
vue
注意 locale.value.toLowerCase() 这一步——vue-i18n 的 locale 值可能是 zh-CN(带大写),而 Element Plus 的语言包 key 是 zh-cn(全小写),必须统一转换。
菜单数据中的国际化处理
在 generateMenuData 转换路由数据时,不翻译标题,只传递 i18n key:
function generateMenuData(routes: RouteRecordRaw[]): AppRouteMenuItem[] {
return routes.map((route) => ({
path: route.path,
meta: {
...route.meta,
// title 保持为 i18n key,不在这里翻译
},
}))
}
typescript
翻译在 MenuItem 组件的模板中完成:
<span>{{ t(data.meta?.title || '') }}</span>
vue
这种方式确保语言切换时,菜单标题能实时更新。
本节小结
- 三种姿势:组件内
useI18n(响应式)、工具函数tt(非响应式)、i18n key 延迟翻译(推荐)。 - Element Plus 国际化:
ElConfigProvider+computed+toLowerCase()统一处理。 - 菜单国际化:meta 中存储 i18n key,渲染时翻译,确保语言切换实时生效。
↑