uniapp国际化方案

本项目当前采用 “多端同构、统一语言包” 的国际化实现方式,H5 与小程序共享同一套 vue-i18n 初始化与语言包加载逻辑,业务层统一使用 $t / useI18n,无需端侧分支。以下内容以现有工程为准,整理清晰的落地方案与使用规范。

一、现状与目标

  1. 多端一致:H5 与小程序均加载 vue-i18n,无需条件编译分支。
  2. 统一入口src/i18n/index.ts 负责语言包聚合与 i18n 实例创建。
  3. 统一使用方式:模板使用 $t,脚本使用 useI18n() 获取 t
  4. 语言状态持久化:Pinia locale store 持久化保存,App 启动时初始化语言。

二、目录结构与语言包组织

src/
├── i18n/
│   ├── index.ts        # i18n 初始化入口
│   ├── zh/             # 中文模块
│   │   ├── demo.ts
│   │   ├── login.ts
│   │   └── ...
│   └── en/             # 英文模块
│       ├── demo.ts
│       ├── login.ts
│       └── ...
├── store/
│   └── locale.ts       # 语言状态持久化
├── components/
│   └── ChangeLocale/   # 切换语言组件
└── main.js             # app.use(i18n)

语言包按模块文件拆分,模块名与文件名保持一致,例如:

  • src/i18n/zh/demo.ts → 使用 demo.xxx 作为 key
  • src/i18n/en/login.ts → 使用 login.xxx 作为 key

三、i18n 初始化机制

项目使用 import.meta.glob 聚合语言包,构建时自动注入:

// src/i18n/index.ts
const messages = {
  zh: {},
  en: {},
}
const zhModules = import.meta.glob('./zh/*.ts', { eager: true })
const enModules = import.meta.glob('./en/*.ts', { eager: true })

最终通过 createI18n 创建实例并全局注入 $t

const i18n = createI18n({
  legacy: false,
  locale: getInitialLocale(),
  fallbackLocale: 'zh',
  messages: loadModuleMessages(),
  globalInjection: true,
})

四、全局挂载与语言初始化

  1. 全局挂载src/main.jsapp.use(i18n) 对所有端生效。
  2. 语言初始化src/App.vueonLaunch 阶段读取本地 locale 或系统语言设置,并同步到 i18nlocale store。
  3. 持久化src/store/locale.ts 使用 Pinia 持久化,存储 key 为 locale

五、业务层使用方式

5.1 模板中使用

<text>{{ $t('demo.iconPreviewTitle') }}</text>

5.2 脚本中使用

import { useI18n } from 'vue-i18n'
const { t, locale } = useI18n()
const title = t('login.login')

5.3 切换语言

项目已有切换组件 src/components/ChangeLocale/ChangeLocale.vue

locale.value = 'en'
useLocaleStore().setLocale('en')

六、编写规范(与项目规则一致)

  1. 禁止硬编码中文:所有展示文本必须走 t('xx.yy')
  2. 模块化 key 结构module.section.item 风格,模块名与语言包文件名一致。
  3. 插值规范:小程序端使用列表插值 {0}/{1},参数传数组,避免具名插值。
  4. 新增模块:新增页面同时补充 src/i18n/zh/*.tssrc/i18n/en/*.ts

七、可选优化方向(当前未落地)

如需进一步缩减小程序包体,可考虑:

  1. 条件编译隔离:将 vue-i18n 初始化与语言包加载包裹到 #ifdef H5
  2. 小程序降级策略:小程序端返回默认中文或只加载 zh
  3. 端侧依赖裁剪:配置 mp-weixin externals 排除 vue-i18n

当前代码未实现上述优化,如需启用请单独评审与改造。

参考: 官方国际化:uniapp.dcloud.net.cn/tutorial/i1…