vue项目国际化处理(i18n)

1.1 前言

关于最近项目实现国际化改造的一些记录,针对 vue 项目,使用 vue-i18n 库。

1.2 对工作量的清晰认识

参考文章:juejin.cn/post/731967...

  • 词条提取翻译:文本要用翻译函数 $t 包裹、词条写入 json、json 和 excel 转换
  • 布局样式修改:文本翻译后可能溢出、排版错乱等,需要针对不同语言分别处理
  • 功能修正:用中文做判断的地方、后端返回的中文等,需要修改原来逻辑
  • 第三方库的国际化:组件库一般都有提供不同语言,但有些库是没有的,那就很麻烦
  • 有些图片或文件包含中文,就需要提供不同语言的版本

从以上 5 点和页面复杂度来正确评估工作量,避免过于乐观!

(可以先拿一个简单页面和一个复杂页面进行国际化整改,记录花费的时间)

1.2 vue-i18n 使用

官网文档:vue-i18n.intlify.dev/guide/advan...

使用总结:

js 复制代码
// main.ts
import i18n from './i18n/create';
app.use(i18n);

// create.ts
import { createI18n } from 'vue-i18n';
import zh-CN from './zh-CN.json';
import en-US from './en-US.json';

const currentLang = localStorage.getItem('lang') || 'zh-CN'; // 从本地存储中获取当前语言
const i18n = createI18n({
  legacy: false, // 使用Composition API模式
  globalInjection: true, // 在组件注入全局Composer实例的属性和方法,这样即使是Composition API模式,也能在模板上直接使用 $t、$i18n等
  locale: currentLang, // 主语言
  fallbackLocale: currentLang, // 备用
  messages: {
    'zh-CN': zh-CN,
    'en-US': en-US,
  },
});

export default i18n;

// zh-CN.json
// 将词条分成【global】和【页面】两大类来维护:能复用的就放在global,页面特有的就放在页面路由名称下
{
  "global": {
    "confirm": "确认",
    "cancel": "取消",
    "enter": "请输入"
  },
  "页面路由名称": {
    "639423-0": "全部阶段"
  }
}

// 组件内使用
$t('orderNew.799657-1') // 引用词条
$t('orderNew.799657-273', [used, total] // 动态拼接词条
:width="{ 'en-US': '150px' }[locale] || '100px'" // 动态设置不同语言样式

import { useI18n } from 'vue-i18n'
// global使用全局Composer实例,也是默认值
// local使用本地Composer实例,只在本地需要语言特殊化处理时使用
const { t: $t, locale } = useI18n({ useScope: 'global' });
const isZhCN = computed(() => locale.value === 'zh-CN')
const isEnUS = computed(() => locale.value === 'en-US')
locale.value = 'en-US'; // 直接修改 locale 就能切换语言

[lang="en-US"] & {
  // 针对en-US做样式调整
}

1.3 维护词条

使用 Excel 管理词条:

  1. 前端先将不同语言 json 合并转换成 excel
  2. 然后产品或测试修改词条翻译(或交给专业的翻译人员处理)
  3. 等翻译改好后,前端再将 excel 转换成不同语言 json

需要实现两个脚本:json 合并转换 excel、excel 导出不同语言 json

假设维护词条的 excel 表格如下:

key zh en
common.ok 确定 OK
common.cancel 取消 Cancel
login.username 用户名 Username
login.password 密码 Password

excel 导出 json 脚本:

js 复制代码
const xlsx = require('xlsx');
const fs = require('fs');
const path = require('path');
const { set } = require('lodash');

const workbook = xlsx.readFile('./i18n.xlsx');
const sheet = workbook.Sheets[workbook.SheetNames[0]];
const data = xlsx.utils.sheet_to_json(sheet);

const langs = ['zh', 'en'];
const result = { zh: {}, en: {} };

data.forEach((row) => {
  const key = row['key'];
  if (!key) return;
  langs.forEach((lang) => {
    set(result[lang], key, row[lang] || '');
  });
});

langs.forEach((lang) => {
  const filePath = path.resolve(__dirname, `./${lang}.json`);
  fs.writeFileSync(filePath, JSON.stringify(result[lang], null, 2), 'utf-8');
  console.log(`输出 ${lang}.json 成功!`);
});

1.3 切换全局语言

关键点:

  1. 切换后当前语言存储在 localStorage,在非 vue 场景使用(比如:初始化 createI18n 时)
  2. 切换后改变 html 的 lang 属性,用于针对改某一语言的样式
  3. 切换后刷新当前页面,使组件重新渲染,接口重新调用
  4. 在请求拦截器的 header 增加 lang 字段,表示当前使用的语言

参考代码:

js 复制代码
const { locale } = useI18n({ useScope: 'global' });
const langStorage = useStorage('lang', locale.value);
const html = document.querySelector('html');
html.setAttribute('lang', locale.value);

function toggleGlobalLocale() {
  locale.value = locale.value === 'zh-CN' ? 'en-US' : 'zh-CN';
  langStorage.value = locale.value;
  const html = document.querySelector('html');
  html.setAttribute('lang', locale.value);
  window.location.reload();
}

1.4 我的国际化处理套路(半自动)

主要依赖的 vscode 插件:Du I18N(感谢作者,抽离中文的功能很好用)

流程:

  1. 打开要国际化的页面,右键选择国际化-扫描中文(Du I18N)
  2. 修复扫描后自动包裹 $t 的大量报错,包括:模板字符串错误、恢复注释和 log 等
  3. 将抽离出的词条用 LLM 翻译,然后复制到对应的 json 中
  4. 代码从头看到尾,收集要处理的情况,打上 TODO
  5. 最后一个个解决,然后自测所有功能

PS:不要想着能有那种完全自动化的插件或库,能给你一次性处理到位。我觉得这是不存在的,即使真的存在,也不一定适用于你的项目。并且生产项目它改了哪些我也得一个个审核自测,否则不放心。

最后推荐一下我的 vscode 插件:vue-i18n 中文搜索定位

这个插件主要解决的问题是:当文件中都是用 $t('key') 引用词条时,能快速通过词条中文搜索定位到使用位置

1.8 结束

更新记录 复制代码
2025/08/10:发布文章
相关推荐
LLLLYYYRRRRRTT6 分钟前
MariaDB 数据库管理与web服务器
前端·数据库·mariadb
胡gh7 分钟前
什么是瀑布流?用大白话给你讲明白!
前端·javascript·面试
universe_0113 分钟前
day22|学习前端ts语言
前端·笔记
teeeeeeemo17 分钟前
一些js数组去重的实现算法
开发语言·前端·javascript·笔记·算法
Zz_waiting.18 分钟前
Javaweb - 14.1 - 前端工程化
前端·es6
掘金安东尼20 分钟前
前端周刊第426期(2025年8月4日–8月10日)
前端·javascript·面试
Abadbeginning20 分钟前
FastSoyAdmin导出excel报错‘latin-1‘ codec can‘t encode characters in position 41-54
前端·javascript·后端
ZXT22 分钟前
WebAssembly
前端
卢叁22 分钟前
Flutter开发环境安装指南
前端·flutter
curdcv_po40 分钟前
Three.js,闲谈3D——智慧XX
前端