如果是 vue-i18n ,我试过三种做法
一:单文件自定义块
```
<i18n>
{
"zh-CN": {
"a": "xxx"
},
"en-US": {
"a": "yyy"
}
}
</i18n>
```
优点是可以快速搞定,AI 工具一直 Tab 就行了,大部分时间花在看 vue-i18n 文档,缺点是零散在几十几百个 vue 文件里,适合那种特别老的项目,不想额外管理 i18n 文件,且页面和文字几乎不会再改动。
二:json 文件
重构 i18n 确实烦人,但是如果还想正常迭代项目只能重构。将所有中文文本抽离出来,大致分类一下,再让 AI 一次性翻译完英文,然后手动一个个去替换原始文本 t('xxx.yyy')。我建议二层嵌套就行,顶多三层嵌套。
三:ts 文件
事先声明我这属于瞎折腾,用 json 方案就行了。
i18n-ally 和 vue-i18n 在 ts 文件上都有一些坑,搞了好久总算能用了,但是跟 json 方案比差不了多少。
这是我的 i18n-ally 的 vscode 配置文件
"i18n-ally.enabledFrameworks": ["vue"],
"i18n-ally.enabledParsers": ["ts"],
"i18n-ally.parsers.typescript.compilerOptions": {
"moduleResolution": "node"
}
这样就能正常识别 ts 文件
这是我的 i18n/index.ts 文件
import zhCN from './locales/zh-CN'
import enUS from './locales/en-US'
const messages: Record<I18n.Language, I18n.LocaleMessage> = {
'zh-CN': zhCN,
'en-US': enUS,
}
const i18n = createI18n({
locale: getStorage(StorageKeyEnum.language, 'zh-CN'),
fallbackLocale: 'en',
messages,
legacy: false,
})
export function setupI18n(app: App) {
app.use(i18n)
}
export function setLocale(locale: I18n.Language) {
i18n.global.locale.value = locale
}
export const t = i18n.global.t
LocaleMessage 是我的翻译文本类型
大概这样
type LocaleMessage = {
icon: {
...
}
route: {
...
}
tab: {
...
}
table: {
...
}
}
然后可以递归得到所有 key 的联合类型
type GetI18nKey<T, K extends keyof T = keyof T> =
K extends string ?
T[K] extends Record<string, unknown> ?
`${K}.${GetI18nKey<T[K]>}`
: K
: never
type I18nKey = GetI18nKey<LocaleMessage>
type RouteKey = GetI18nKey<LocaleMessage, 'route'>
type TableKey = GetI18nKey<LocaleMessage, 'table'>
在你需要硬编码比如路由元信息等地方用 I18nKey 类型进行限定就能完全消除硬编码