5. 处理动态内容的国际化
5.1 平台限制与解决方案
根据uni-app官方文档,由于运行平台限制,目前在小程序和App端不支持插值方式定义国际化。这意味着以下方式在小程序和App端无法正常工作:
// 这种方式在小程序和App端不支持
t('hello', { name: '小明' }) // 使用命名参数
t('hello', ['小明']) // 使用数组参数
为了解决这个问题,我们需要使用自定义的插值方法来处理带参数的翻译。
5.2 带参数的翻译
// 在语言文件中定义带占位符的文本
// zh-CN.json
{
"greeting": "你好,{0}!",
"welcome": "欢迎{0}来到{1}"
}
// 使用时传入参数
t('greeting', ['小明'])
// 输出:你好,小明!
t('welcome', ['小明', 'wot-design-uni'])
// 输出:欢迎小明来到wot-design-uni
注意:我们使用{0}, {1}这样的数字索引占位符,而不是使用命名参数如{name}。这是因为小程序和App端不支持命名参数的插值方式。
5.3 实现插值工具函数
// src/locale/utils.ts
/**
* 替换字符串中的占位符
* @param template 模板字符串,如 "Hello {0}, welcome to {1}"
* @param values 要替换的值数组
* @returns 替换后的字符串
*/
export function interpolateTemplate(template: string, values: any[]): string {
return template.replace(/{(\d+)}/g, (_, index) => values[index] ?? '')
}
5.4 扩展t函数支持数组参数
由于小程序和App端的限制,我们需要扩展vue-i18n的t函数,使其能够处理数组参数并应用我们的插值方法:
// src/locale/index.ts
import { createI18n } from "vue-i18n"
import zhCN from "./zh-CN.json"
import enUS from "./en-US.json"
import { Locale } from "@wot-ui/ui"
import WotEnUS from "@wot-ui/ui/locale/lang/en-US"
import { interpolateTemplate } from "./utils"
Locale.add({ "en-US": WotEnUS })
const messages = {
"zh-CN": {
...zhCN
},
"en-US": {
...enUS
}
}
// 创建i18n实例
const i18n = createI18n({
locale: uni.getStorageSync("currentLang") || "zh-CN", // 默认语言
fallbackLocale: "zh-CN", // 回退语言
messages, // 语言包
legacy: false, // 启用Composition API模式
globalInjection: true // 全局注入 $t 等方法到模板
})
// 同步组件库语言
Locale.use(i18n.global.locale.value)
uni.setLocale(i18n.global.locale.value)
// 扩展t函数,支持数组参数插值
// 这是解决小程序和App端不支持插值方式的关键步骤
const originalT = i18n.global.t
i18n.global.t = (key, param1, param2) => {
const result = originalT(key, param1, param2)
// 检测是否传入了数组参数,如果是则使用我们的插值方法处理
if (Array.isArray(param1)) {
return interpolateTemplate(result, param1)
}
return result
}
export default i18n
这种扩展方式的优点是:
- 保持了与vue-i18n原有API的兼容性
- 在小程序和App端也能使用类似的参数传递方式
- 统一了不同平台的国际化使用体验
需要注意的是我们仅实现了数组参数的插值,如果需要支持更多参数类型,可以进一步扩展。
5.5 使用示例
<template>
<!-- 在模板中使用 -->
<view>{{ $t('greeting', [username]) }}</view>
<view>{{ $t('welcome', [username, 'wot-design-uni']) }}</view>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const username = ref('小明')
// 在JS/TS代码中使用
const message = t('greeting', [username.value])
</script>
注意:这种方法在H5、App和小程序等所有平台上都能正常工作,因为我们使用了自定义的插值方法来处理参数,绕过了小程序和App端的限制。
6. 组件库的国际化
WotUI组件库本身支持国际化,我们只需要参考国际化文档进行配置即可。
6.1 同步应用和组件库的语言
使用useI18nSync钩子可以同步应用和组件库的语言设置:
// 同步组件库语言设置
if (syncComponentLib) {
Locale.use(locale)
}
7. pages.json的国际化
注意:建议仔细阅读uni-app国际化文档。
7.1 页面标题国际化
在uni-app中,pages.json中的页面标题可以通过占位符实现国际化:
// pages.json
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "%index-title%"
}
}
]
}
7.2 语言文件配置
在语言文件中添加对应的翻译:
// zh-CN.json
{
"index-title": "首页"
}
// en-US.json
{
"index-title": "Home"
}
7.3 平台差异处理
- H5平台:直接支持占位符方式
- 其他平台:可以使用自定义Tabbar和Navbar实现
注意:小程序下不支持这种国际化方案,也可以使用设置tabbar和navigationbar的API来设置文字。或者废弃原生tabbar和navigationbar,使用自定义方式,详情参考uni-app官方文档
8. i18n-ally插件
8.1 插件概述
i18n-ally是VSCode的一款国际化插件,提供以下核心功能:
- 自动检测项目中的硬编码文本
- 一键提取待翻译内容
- 多语言文件管理
- 翻译辅助工具集成
8.2 安装与配置
-
安装插件:
- 在VSCode扩展市场搜索并安装
i18n-ally - 安装完成后重启VSCode
- 在VSCode扩展市场搜索并安装
-
基本配置:
- 在项目根目录创建
.vscode/settings.json文件 - 添加以下基础配置:
// .vscode/settings.json
{
"i18n-ally.sourceLanguage": "zh-CN", // 项目的源语言(基准语言),用来作为自动翻译的参考基准
"i18n-ally.displayLanguage": "zh-CN", // VS Code 插件界面中默认显示的语言(如悬浮提示中显示的翻译预览)
"i18n-ally.localesPaths": ["src/locale"], // 翻译文件(如 zh-CN.json, en-US.json)的存放目录
"i18n-ally.keystyle": "flat", // 翻译键的样式:flat(扁平单层,如 "settings.title")或 nested(嵌套 JSON 对象)
"i18n-ally.sortKeys": true, // 保存翻译文件时,是否按字母顺序对多语言键名进行自动排序
} - 在项目根目录创建

8.3 核心功能详解
8.3.1 自动检测
-
扫描范围:HTML标签内容、Vue模板、JS/TS代码
-
支持配置检测规则:
"i18n-ally.extract.parsers.html": { "attributes": ["text", "title", "alt", "placeholder", "label", "aria-label"], // 提取文本时,允许扫描和提取的 HTML/组件属性 "ignoredTags": ["script", "style"], // 提取文本时忽略的 HTML 标签,避免误提取 "vBind": true, // 是否支持提取 Vue 绑定属性(如 :title="xxx") "inlineText": true // 是否支持提取 HTML 标签内的普通行内文本 },

8.3.2 一键提取
- 自动生成翻译键
- 保持语言文件结构一致
- 支持批量处理

注意:提取的翻译键会自动添加到语言文件中,无需手动添加,但是批量提取的翻译键值会丢失插值参数,例如:
哈哈哈${232}应当生成为t('hahaha', [232]),但实际上生成的是t('ha-ha-ha-232-0'),可以选择手动添加插值参数,或者结合8.4.1进行优化
8.3.3 翻译辅助
i18n-ally内置翻译API支持,这里我们使用百度翻译API作为示例:
- 注册账号 :访问百度翻译开放平台注册账号
- 创建应用:获取APP ID和密钥
- 配置插件:

8.4 高级配置
8.4.1 重构模板
"i18n-ally.refactor.templates": [
{
"source": "html-inline",
"template": "{{ $t('{key}'{args}) }}" // 行内普通文本提取后替换生成的模板格式
},
{
"source": "html-attribute",
"template": "$t('{key}'{args})" // HTML 属性中的文本提取后替换生成的模板格式
},
{
"source": "js-string",
"template": "t('{key}'{args})" // JS 字符串提取后替换生成的模板格式 (适用于 Vue3 script)
},
{
"source": "js-template",
"template": "t('{key}'{args})" // JS 模板字符串提取后替换生成的模板格式 (适用于 Vue3 script)
}
],
重构模板后,提取的翻译键会自动添加插值参数,例如:哈哈哈${232}${111}会生成为携带插值参数的格式t('hahaha', 232, 111),不过vue-i18n的t方法不支持这种格式,所以我们需要再展t函数,支持可变参数,并将其作为数组参数插值。
// src/locale/index.ts
import { createI18n } from "vue-i18n"
import zhCN from "./zh-CN.json"
import enUS from "./en-US.json"
import { Locale } from "@wot-ui/ui"
import WotEnUS from "@wot-ui/ui/locale/lang/en-US"
import { interpolateTemplate } from "./utils"
Locale.add({ "en-US": WotEnUS })
const messages = {
"zh-CN": {
...zhCN
},
"en-US": {
...enUS
}
}
// 创建i18n实例
const i18n = createI18n({
locale: uni.getStorageSync("currentLang") || "zh-CN", // 默认语言
fallbackLocale: "zh-CN", // 回退语言
messages, // 语言包
legacy: false, // 启用Composition API模式
globalInjection: true // 全局注入 $t 等方法到模板
})
// 同步组件库语言
Locale.use(i18n.global.locale.value)
uni.setLocale(i18n.global.locale.value)
// 这是解决小程序和App端不支持插值方式的关键步骤
const originalT = i18n.global.t
// 扩展t函数,支持数组参数插值
i18n.global.t = (key, ...args) => {
// 处理对象参数场景: t(key, {key1: value1, key2: value2})
if (args.length === 1 && typeof args[0] === "object" && !Array.isArray(args[0])) {
const result = originalT(key, ...args)
return result
}
// 处理数组参数场景: t(key, [arg1, arg2])
if (args.length === 1 && Array.isArray(args[0])) {
const result = originalT(key, args[0])
return interpolateTemplate(result, args[0])
}
// 处理可变参数场景: t(key, arg1, arg2, ...)
if (args.length > 1 && args.every(arg => typeof arg !== "object")) {
return interpolateTemplate(originalT(key, args), args)
}
// 处理默认场景: t(key) 或 t(key, defaultMessage) 或 t(key, plural) 等
const result = originalT(key, ...args)
return result
}
export default i18n
8.4.2 忽略规则
"i18n-ally.extract.ignored": [
"特定文本",
"正则表达式",
]
总结
至此,我们完成了国际化配置,并使用 i18n-ally 插件实现了对 Vue 组件的自动提取和翻译。如果本文对你有所帮助,请点赞、收藏、转发,让更多的人了解和使用国际化配置。