国际化多语言
-
@nuxtjs/i18n是集成了vue-i18n -
多语言code
场景
- 1、切换多语言
- 2、app内嵌h5页面,app切换语言时,h5也需要多语言切换
- 3、获取语言可以多种方式
- h5中手动切换语言
- 内嵌的app中,可通过请求头、cookie等方式获取当前语言,和客户端/后端约定好
相关方法
-
useI18n
- mergeLocaleMessage动态合并语言对象,用于合并多语言数据
-
useLocalePath
- localePath接收两个参数,一个是目标路由,一个是目标语言,根据当前语言区域解析路径
- 用于生成路径跳转链接,生成带有语言前缀的路径
-
defineI18nRoute
-
为当前页面路由定义每种语言下的路径(slug),适合处理不同语言页面 URL 不一致
-
想让中文路径是
/guanyu,英文路径是/about,就可以这样做defineI18nRoute({paths: {en: '/about',zh: '/guanyu'}})
-
每个页面多语言切换
一般情况下,会在根目录定义一个通用的多语言文件,每个页面都可以读取在根目录定义好的多语言,但是有些页面需要展示额外不同的多语言,那么页面上需要自定义多语言文件,按页面来加载不同语言
- 1、全局通用语言:全局通用的多语言,定义在根目录的
lang - 2、页面特地语言:在每个页面定义一个
lang为文件夹,来存放多语言
├── lang/ # 全局通用语言文件
│ ├── en.json
│ └── zh-CN.json
├── pages/
│ └── about/ # 示例页面
│ ├── lang/ # 页面级语言文件
│ │ ├── en.json
│ │ └── zh-CN.json
│ └── index.vue
在页面加载特定语言
mergeLocaleMessage(locale, messages):动态合并语言对象- 可将当前语言
locale合并到已注册的语言环境信息中
- 可将当前语言
<template>
{{ $t("welcome") }}
{{ $t("username") }}
</template>
<script setup lang="ts">
const { locale, mergeLocaleMessage } = useI18n()
async function loadPageMessages(lang: string) {
const pageMessages = await import(`~/pages/home/locales/${lang}.json`)
mergeLocaleMessage(lang, pageMessages.default)
}
// 初始加载 (保证在客户端和服务端都执行,避免闪烁)
await loadPageMessages(locale.value)
// 切换语言时重新加载
watch(locale, async (newLang) => {
await loadPageMessages(newLang)
})
</script>
URL多语言前缀配置
配置 strategy
- 路由策略
选项说明:
- 默认是英文en,不加前缀
| 值 | 说明 | 示例 URL(默认语言为 en) |
|---|---|---|
'prefix' | 所有语言都加前缀 | /en, /ja |
'prefix_except_default' ✅ | 默认语言不加前缀,其它加 | /(en),/ja |
'prefix_and_default' | 所有语言都加前缀,包括默认语言 | /en, /ja |
'no_prefix' | 所有语言都不加前缀(仅用 cookie/localStorage 管控) | /(始终),不能用于 SEO |
懒加载语言资源
- 配置
lazy设置为ture - 是否按需加载语言 JSON 文件(而不是一次性加载所有语言)。
i18n 配置文件
i18n/i18n.config.ts- 可以在
<rootDir>/i18n目录中创建一个i18n.config.ts文件
- 可以在
i18n遇到问题坑
NuxtLink会存在问题,跳转会丢失当前语言路由- 解决:用i18n提供的
NuxtLinkLocale替代NuxtLink
- 解决:用i18n提供的
注意点以及优化
- 避免重复加载多语言
- 如缓存
- 自动化加载自定义的多语言
- 如通过插件,自动监听当前路由, 来加载当前路由页面的多语言
- 多语言的按需加载
- 减少多语言的打包体积
- SSR的兼容性
- 注意语言的加载情况, 避免出现闪烁
- 为什么会出现闪烁? 比如第一次加载全局的语言包,第二次加载页面级别的特定的语言包
- 首次渲染的时候,首先会执行服务端渲染ssr, 服务端生成HTML页面结构之后,给到客户端,这时候客户端才会执行相关方法
- 避免使用onBeforeMount、onMounted来加载语言包,因为这2个hooks是在客户端执行,可能会出现闪烁情况 (因为需要等到第二次在执行)
- 解决方法:
- 1、直接在setup执行,在服务端渲染和客户端都会执行一样逻辑
- 2、使用watch监听来动态加载切换语言包