ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Vue3 国际化实战:vue-i18n 搭配 VSCode i18n Ally 的自动化翻译工作流

Vue3 国际化实战:vue-i18n 搭配 VSCode i18n Ally 的自动化翻译工作流 1. Vue3 项目里手动维护语言包到底有多痛先说说我遇到过的真实场景。一个后台管理系统从登录页到数据看板一共 40 多个组件产品经理要求中英双语。最开始我的做法很朴素在src/lang/zh.json和en.json里手动加键值模板里写$t(login.title)然后复制一份到英文文件里翻译。前两周还行等到第三个迭代问题全冒出来了。第一个坑是键名对不上。中文文件里我写了user.profile.name英文文件里手滑写成user.profile.username页面切到英文直接显示原始 key用户看到一串user.profile.username挂在界面上。第二个坑是漏翻译。新增了 20 个文案中文文件加完了英文文件忘了同步切语言时一半中文一半英文。第三个坑最要命改文案的时候不知道这个 key 在哪些组件里被引用删掉一个 key 结果三个页面白屏。这些问题的根源在于语言包和组件代码之间没有强关联。你写$t(xxx)的时候编辑器不知道xxx到底存不存在你改 JSON 的时候编辑器也不知道哪个组件在用这个 key。纯靠人眼比对项目一大必然出错。后来我把 vue-i18n 和 VSCode 的 i18n Ally 插件组合起来用才算把这条链路打通。这套工作流能解决三件事键值自动提取选中中文直接生成 key 并写入 JSON、翻译补全中文写完英文一键生成、缺失校验哪个 key 在哪个语言里缺了面板里一目了然。下面我把从零接入的完整过程拆开讲包括配置片段和踩过的坑。这套方案适合谁适合正在做 Vue3 项目、有至少两种语言需求、并且用 VSCode 作为主力编辑器的前端。如果你用的是 WebStorm 或者别的编辑器i18n Ally 也有对应版本但本文以 VSCode 为准。整个流程不需要额外服务本地就能跑通。2. vue-i18n 9.x 接入与 i18n Ally 环境准备2.1 安装依赖与目录结构设计vue-i18n 在 Vue3 里必须用 9.x 版本8.x 是给 Vue2 用的装错了会报createI18n is not a function。安装命令npm install vue-i18n9目录结构我建议这样设计原因是 i18n Ally 和 vscode-icons 都能识别这些命名图标会变成地球或者语言标志找文件快src/ lang/ index.js # i18n 实例配置 zh.json # 中文语言包 en.json # 英文语言包lang、locales、i18n这几个目录名都在插件的默认扫描范围内。语言包文件用 JSON 格式因为 i18n Ally 对 JSON 的读写支持最完整注释虽然不保留但胜在稳定。2.2 创建 i18n 实例并全局注册src/lang/index.js的内容如下注意legacy: false这行不设置的话 Composition API 里的useI18n拿不到东西import { createI18n } from vue-i18n import EN from ./en.json import ZH from ./zh.json const messages { zh: { ...ZH }, en: { ...EN } } const i18n createI18n({ locale: localStorage.getItem(LANG) || zh, legacy: false, globalInjection: true, messages }) export default i18nglobalInjection: true让模板里可以直接用$t不用每个组件都 import。locale从 localStorage 读这样刷新页面语言不丢。然后在main.js里注册import { createApp } from vue import App from ./App.vue import i18n from ./lang const app createApp(App) app.use(i18n) app.mount(#app)2.3 安装 i18n Ally 并生成 settings.json在 VSCode 扩展市场搜i18n Ally作者是 Lokalise安装后重启。重启完打开项目右下角会弹出提示「检测到翻译文件夹 src/lang」点确认插件会在项目根目录的.vscode/settings.json里自动写入localesPaths。如果没弹提示手动建.vscode/settings.json也行。完整的配置片段如下每一项我都标了作用{ i18n-ally.localesPaths: [src/lang], i18n-ally.keystyle: nested, i18n-ally.sortKeys: true, i18n-ally.namespace: true, i18n-ally.enabledParsers: [json], i18n-ally.sourceLanguage: zh, i18n-ally.displayLanguage: zh, i18n-ally.extract.keygenStyle: camelCase, i18n-ally.enabledFrameworks: [vue] }几个关键项解释一下。keystyle选nested表示支持user.profile.name这种嵌套写法选flat就是扁平的一整串。sourceLanguage是翻译源插件以中文为基准去补其他语言。displayLanguage控制面板里显示哪个语言的内容不要写死成某个语言后就不管了否则切换显示语言不生效。extract.keygenStyle设成camelCase提取中文时自动生成驼峰 key比如「当前语言类型」会变成dangQianYuYanLeiXing比拼音全拼好看点。配置完如果没生效按CtrlShiftP输入i18n Ally: Refresh手动刷新一次。3. 可复制的 i18n 配置与 i18n Ally settings.json 片段3.1 语言包 JSON 的嵌套写法先看两个语言包文件的实际内容。中文zh.json{ login: { title: 登录, username: 用户名, password: 密码, submit: 提交 }, dashboard: { welcome: 欢迎回来, logout: 退出登录 } }英文en.json{ login: { title: Login, username: Username, password: Password, submit: Submit }, dashboard: { welcome: Welcome back, logout: Logout } }嵌套结构的好处是 key 有层级login.title一眼知道是登录页标题。i18n Ally 的keystyle: nested就是配合这种写法。3.2 模板与 JS 中的调用方式模板里直接用$ttemplate h1{{ $t(login.title) }}/h1 button clickhandleSubmit{{ $t(login.submit) }}/button /templateJS 里用useI18n解构出t注意要放在setup里script setup import { useI18n } from vue-i18n const { t, locale } useI18n() const handleSubmit () { console.log(t(login.submit)) } const switchLang (lang) { locale.value lang localStorage.setItem(LANG, lang) } /scriptlocale是响应式的改了之后模板里所有$t会自动重新渲染不用手动刷新。3.3 i18n Ally 的完整 settings.json 与路径说明把 2.3 的配置再补全一点加上翻译引擎和审阅相关{ i18n-ally.localesPaths: [src/lang], i18n-ally.keystyle: nested, i18n-ally.sortKeys: true, i18n-ally.namespace: true, i18n-ally.enabledParsers: [json], i18n-ally.sourceLanguage: zh, i18n-ally.displayLanguage: zh, i18n-ally.extract.keygenStyle: camelCase, i18n-ally.enabledFrameworks: [vue], i18n-ally.editor.preferEditor: true, i18n-ally.annotationInPlace: true }annotationInPlace: true让翻译内容直接显示在代码行内不用鼠标悬停。editor.preferEditor: true表示编辑翻译时用编辑器弹窗而不是内联输入框改长文案方便。这里要提醒一句i18n Ally 的自动翻译功能依赖外部翻译服务配置里可以指定引擎但这部分需要你自己有对应的服务账号插件本身不提供翻译能力。如果只是本地开发、不想接外部服务完全可以手动填英文插件负责的是「发现缺失」和「写入文件」翻译那一步手动做也很快。4. 验证请求提取、补全与缺失校验的完整操作4.1 从硬编码中文提取 key打开一个写了中文的 Vue 文件比如template div h2用户中心/h2 p当前语言类型{{ currentLang }}/p /div /template按CtrlShiftP输入i18n Ally: Extract或者点侧边栏的 i18n Ally 图标打开控制面板展开Hard-coded strings [beta]这一项。你会看到「用户中心」和「当前语言类型」被列出来。右键选择「提取所有」插件会做两件事把模板里的中文替换成$t(yongHuZhongXin)这样的调用同时把键值写进zh.json。替换后的模板template div h2{{ $t(yongHuZhongXin) }}/h2 p{{ $t(dangQianYuYanLeiXing) }}{{ currentLang }}/p /div /templatezh.json里新增{ yongHuZhongXin: 用户中心, dangQianYuYanLeiXing: 当前语言类型 }注意 JS 里的字符串提取插件默认可能替换成 Vue2 的this.$t语法。Vue3 的script setup里没有this需要手动改成t(xxx)或者提取前在设置里确认框架是 vue3。这是踩过的坑提取完记得扫一眼 JS 部分。4.2 补全英文翻译与缺失校验切到en.json你会发现刚才新增的两个 key 是空的或者根本没出现。i18n Ally 的控制面板里有个「缺失翻译」区域列出所有在zh.json有、但en.json没有的 key。手动补的话直接在en.json里加{ yongHuZhongXin: User Center, dangQianYuYanLeiXing: Current language type }保存后控制面板的缺失数量会减少。如果配置了翻译引擎点「翻译缺失文案」可以批量生成但生成结果建议人工过一遍机器翻译的术语经常不准。校验是否对齐有个简单办法在控制面板顶部看两个语言的 key 数量是否一致。不一致就说明有遗漏。也可以打开任意一个.vue文件把鼠标悬停在$t(xxx)上如果 key 不存在插件会标黄警告。4.3 新增语言包后的一键验证假设要加日语新建ja.json然后在src/lang/index.js里引入import JA from ./ja.json const messages { zh: { ...ZH }, en: { ...EN }, ja: { ...JA } }重启 VSCodei18n Ally 会自动识别新语言。控制面板里会多出日语一列缺失的 key 全部列出来。这时候你可以逐个补也可以导出成表格交给翻译同学。验证键对齐的操作在控制面板里点右上角的「审阅」图标会打开一个 diff 视图左边中文右边日语逐条对照。确认无误后切到页面点语言切换看日语是否正常显示。如果某个 key 显示成原始字符串说明ja.json里漏了或者拼错了。5. 本篇常见错误排查5.1 报错Uncaught SyntaxError: Must be called at the top of a setup function这个报错通常是因为useI18n()写在了setup外面或者写在了异步回调里。useI18n依赖 Vue 的组件上下文必须在setup同步执行阶段调用。检查你的代码// 错误写法 const { t } useI18n() // 在 setup 外 // 正确写法 script setup import { useI18n } from vue-i18n const { t } useI18n() /script5.2 报错Cannot read properties of undefined (reading choices)这个报错一般出现在 i18n Ally 尝试读取语言包但路径不对的时候。检查.vscode/settings.json里的localesPaths是否指向了正确的目录。如果你的语言包在src/lang/locales/下面那配置要写成[src/lang/locales]不能只写src/lang。还有一种情况是 JSON 文件格式错误比如多了个逗号或者少了引号。VSCode 会标红修好保存再刷新插件。5.3 报错401 Unauthorized或翻译服务连接失败如果你配置了外部翻译引擎报 401 说明密钥不对或者过期了。检查引擎配置里的 API Key。如果报connect ECONNREFUSED 127.0.0.1:xxxxx说明插件在尝试连接本地代理但没连上。这种情况要么检查代理配置要么干脆关掉自动翻译手动填。5.4 报错OAuth token expired或登录态失效部分翻译服务用 OAuth 授权token 有有效期。过期后插件会提示重新登录。在控制面板里找到对应引擎点重新授权即可。如果一直失败检查系统时间是否准确OAuth 对时间偏差敏感。5.5 提取后 key 重复或覆盖i18n Ally 提取时如果发现相同的中文已经存在对应 key会复用而不是新建。但如果你的keystyle设置变了比如从flat改成nested旧 key 可能对不上导致重复。解决办法是提取前先统一keystyle提取后手动清理重复项。控制面板里可以搜索 key重复的会标出来。5.6 语言切换后页面不更新检查locale是不是响应式的。如果你在index.js里把locale写死成字符串切换不会生效。正确做法是通过useI18n拿到locale的 ref或者用i18n.global.locale.value en。另外localStorage的读写要放在切换逻辑里否则刷新后回到默认语言。6. 把这条工作流用顺手的几个建议整套流程跑通之后日常开发基本就是写中文 → 提取 key → 补英文 → 切语言验证。i18n Ally 的控制面板可以常驻侧边栏随时看缺失数量。如果你项目里语言包很大建议按模块拆分 JSON 文件比如login.json、dashboard.json然后在index.js里合并。i18n Ally 支持多个 locales 路径配置成数组就行。这样改登录页的文案不会影响看板模块git diff 也清晰。另外团队协作时把.vscode/settings.json提交到仓库保证每个人插件配置一致。不然你提取的 key 是驼峰同事提取的是下划线合并时冲突不断。最后提一句i18n Ally 的自动翻译只是辅助核心术语和品牌词一定要人工确认。机器翻译把「提交」翻成Submit没问题但把「确定」翻成Sure就不合适了应该是Confirm。这类细节靠插件解决不了得靠人。如果你在配置过程中遇到插件连不上翻译服务的情况检查一下网络环境是否允许访问对应的服务地址。本地开发阶段手动填英文完全够用不必强求自动化。
返回列表