HomeBrowseUpload
← Back to registry
// Skill profile

国际化翻译 Skill

name: dy-skill-i18n

by anyaoqi · published 2026-04-01

数据处理API集成
Total installs
0
Stars
★ 0
Last updated
2026-04
// Install command
$ claw add gh:anyaoqi/anyaoqi-dy-skill-i18n
View on GitHub
// Full documentation

---

name: dy-skill-i18n

description: 处理前端国际化翻译工作。当用户提到需要做国际化、i18n、翻译、多语言支持时使用此 skill。主要功能:1) 识别代码中的硬编码静态文字;2) 判断是否应使用现有公共翻译或需要新增;3) 将翻译添加到对应的语言文件中;4) 将硬编码替换为国际化调用;5) 检查翻译完整性和正确性。

---

# 国际化翻译 Skill

目录

  • [核心原则](#核心原则)
  • [工作流程](#工作流程)
  • [常见问题处理](#常见问题处理)
  • [翻译准确性要求](#翻译准确性要求)
  • [注意事项](#注意事项)
  • [验证与错误处理](#验证与错误处理)
  • ---

    概述

    此 skill 用于处理前端项目的国际化翻译工作。当你需要将代码中的硬编码中文(或英文)文字转换为国际化支持时使用。

    **前提**:以实际项目结构为准,不破坏现有项目规则。

    ---

    核心原则

    1. **以实际项目结构为准** - 不假设固定目录结构,根据项目现有配置灵活调整

    2. **配置放对应位置** - 公共翻译放公共目录,模块翻译放模块目录,不混淆

    3. **优先复用现有翻译** - 已有相同含义的翻译时直接使用,不要重复添加

    4. **只翻译静态文字** - 不翻译后端接口返回的数据、字典/枚举中的内容

    5. **不破坏现有规则** - 所有修改基于项目现有规则,不改变现有结构

    ---

    工作流程

    Step 1: 了解项目结构

    首先探索项目的国际化配置:

    1. 查找语言文件目录(常见名称:lang, locales, i18n, language, messages)

    2. 确认目录结构模式:

    - **有模块区分**:是否存在 common/, module/, 或按模块名划分的子目录

    - **无模块区分**:所有翻译是否都在一个或少数几个文件中

    3. 确认文件命名规范(如 zh_CN.ts, zh-CN.ts, en.ts, en_US.ts 等)

    4. 确认国际化调用方式(如 $t(), t(), useI18n() 等)

    5. 确认支持的语言种类(是否只有中英文,还是支持更多语言)

    6. 确认是否使用了 vue-i18n 的特殊功能(复数、插值等)

    Step 2: 识别需要翻译的内容

    **✅ 需要翻译**:

  • 静态显示的中文/英文字符串
  • 按钮文字、提示信息、表单标签
  • 表格列标题、对话框标题
  • 占位符文字、选项文字
  • **❌ 不需要翻译**:

  • 从后端 API 返回的数据
  • 字典/枚举中获取的内容
  • 变量和动态计算的值
  • 数字、日期格式(需要使用专门的格式化方法)
  • 技术性错误信息(后端返回的 error message)
  • Step 3: 判断翻译放哪里

    根据项目实际结构判断翻译应该添加到哪里:

    #### 情况A: 项目有模块区分

    lang/
    ├── common/        # 公共翻译
    │   ├── zh.ts
    │   └── en.ts
    ├── module/        # 模块翻译
    │   ├── product/
    │   ├── order/
    │   └── ...
    └── index.ts

    **决策规则**:

  • 如果是**通用性质**的翻译(如:新增、编辑、删除、搜索、重置、确定、取消、请输入、请选择等)→ 放 `common/`
  • 如果是**特定业务模块**的翻译(如:产品名称、订单状态,品牌分类等)→ 放对应模块目录
  • #### 情况B: 项目无模块区分

    lang/
    ├── zh_CN.ts
    ├── en_US.ts
    └── index.ts

    **决策规则**:

  • 所有翻译都直接添加到对应的语言文件中
  • 使用有前缀的 key 区分不同模块,如 `product.*`, `order.*`, `common.*`
  • #### 情况C: 其他结构

    根据项目实际结构灵活处理:

  • 可能存在多个语言文件(按语言分、按模块分、混合分)
  • 可能使用 JSON 格式或 TS 格式
  • 总之**遵循项目现有模式,不打破现有结构**
  • Step 4: 添加翻译

    1. **检查现有翻译** - 先搜索是否已有相同含义的翻译,有则复用

    2. **新增翻译 key** - 如果没有,添加新的翻译

    3. **确保所有支持的语言一致** - 添加时同步添加所有支持的语言,保持 key 路径一致

    **添加位置判断**:

    IF 项目有 common/ 或类似的公共目录 THEN
      IF 翻译是通用性质的 THEN
        添加到公共目录
      ELSE
        添加到对应模块目录
    ELSE
      添加到主语言文件中,使用模块前缀区分

    Step 5: 替换硬编码

    根据项目实际的调用方式替换。常见使用方式如下:

    <!-- Template 中使用 $t -->
    {{ $t("key.path") }}
    
    <!-- 在 script 中使用 -->
    <script setup>
    const { t } = useI18n();
    const text = t("key.path");
    </script>
    
    <!-- 属性绑定 -->
    <el-input :placeholder="t('key.path')" />

    Step 6: 检查验证

    1. **完整性检查**:

    - 所有支持的语言翻译都已添加

    - key 路径在所有语言文件中一致

    2. **正确性检查**:

    - 翻译 key 正确

    - 页面显示正常

    3. **遗漏检查**:

    - 扫描文件确认没有遗漏的硬编码

    - 检查相似场景是否需要同样处理

    ---

    常见问题处理

    Q1: 如何判断是公共翻译还是模块翻译?

    通用性质 = 任何模块都可能用到
    - 操作类:新增、编辑、删除、查看、导入、导出、提交、审核
    - 提示类:确定、取消、关闭,保存、成功、失败
    - 占位符类:请输入、请选择、开始日期、结束日期
    - 表格类:序号、操作、状态
    
    模块特有 = 只有特定模块使用
    - 产品名称、产品编码、产品分类
    - 订单号、订单状态
    - 客户名称、客户电话

    Q2: 项目没有模块目录怎么办

    直接添加到主语言文件中,使用模块前缀区分:

    // zh_CN.ts
    export default {
      common: {
        action: { add: "新增", edit: "编辑" },
      },
      product: {
        name: "产品名称",
        code: "产品编码",
      },
      order: {
        no: "订单号",
        status: "订单状态",
      },
    };

    Q3: 已有公共翻译但想保持模块独立性

    如果业务确实需要独立管理(如不同模块由不同人维护),可以在模块目录中重复定义,但建议优先复用公共翻译。

    Q4: 如何处理动态参数/插值

    如果翻译中需要动态参数(如用户名、数量、时间等):

    1. **在 key 中使用占位符**:

    ```typescript

    // zh_CN.ts

    export default {

    deleteSuccess: "删除成功,共 {count} 条记录",

    welcome: "欢迎 {username} 登录系统",

    selectedCount: "已选择 {n} 项",

    };

    ```

    2. **在组件中传递参数**:

    ```vue

    <!-- 使用对象参数 -->

    {{ $t("deleteSuccess", { count: deletedCount }) }}

    <!-- 在 script 中 -->

    <script setup>

    const { t } = useI18n();

    const message = t("deleteSuccess", { count: deletedCount });

    </script>

    ```

    3. **注意事项**:

    - 遵循项目现有的插值语法(占位符格式可能不同,如 `{count}` 或 `%{count}`)

    - 占位符命名应简洁明了

    - 确保所有语言中占位符名称一致

    Q5: 如何处理复数形式

    如果项目使用 vue-i18n 的复数功能:

    // zh_CN.ts(中文通常不需要复数变化,使用相同形式)
    export default {
      itemCount: "{n} 个项目 | {n} 个项目",
    };
    
    // en_US.ts
    export default {
      itemCount: "{n} item | {n} items",
    };

    使用方式:

    {{ $t("itemCount", { n: count }, count) }}

    vue-i18n 会根据 count 的值自动选择单数或复数形式。

    **注意**:如果项目没有使用复数功能,将复数和单数分别定义为不同的 key,如 `itemCount` 和 `itemCount_plural`。

    Q6: 如何处理日期/数字/货币格式化

    日期、数字、货币通常需要专门的格式化方法,**不要**使用简单的翻译:

    1. **使用项目现有的格式化方法**:

    - 查找项目中是否有现成的格式化工具

    - 如使用 `dayjs`, `Intl.NumberFormat` 等

    2. **如果确实需要翻译日期格式**:

    ```typescript

    // 仅翻译格式说明文字,不翻译实际日期

    dateFormat: {

    year: '年',

    month: '月',

    day: '日'

    }

    ```

    3. **数字和货币**:

    ```typescript

    // 建议使用专门的格式化,不走翻译

    // 如:Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' })

    ```

    Q7: 如何处理 UI 框架组件的国际化

    对于 Element Plus、Ant Design 等 UI 框架的组件:

    1. **遵循项目配置** - 查看项目是否已经全局配置了框架的 i18n

    2. **组件自带属性** - 很多组件有内置的 i18n 属性(如 `empty-text`, `confirm-btn-text` 等)

    3. **使用项目配置** - 如果项目有全局的组件文案配置,优先使用

    <!-- Element Plus 示例 -->
    <el-table :data="list" :empty-text="$t('common.table.empty')">
    </el-table>

    Q8: 如何处理后端返回的错误信息

    1. **如果后端返回的是国际化 key** - 直接使用,无需翻译

    2. **如果后端返回原始错误信息** - 建议:

    - 在前端建立错误码映射表

    - 或让后端支持国际化 key 返回

    3. **如果是业务性质的提示** - 可以翻译:

    ```typescript

    // 错误码映射

    error: {

    1001: '用户名不存在',

    1002: '密码错误',

    1003: '账号已被锁定'

    }

    ```

    Q9: 项目需要支持多种语言怎么办

    1. **确认支持的语言种类** - 查看项目现有语言文件

    2. **所有语言同步添加** - 新增翻译时,必须同时添加所有支持的语言

    3. **遵循语言代码规范** - 使用项目现有的语言代码格式(如 zh-CN vs zh_CN)

    Q10: 翻译 key 冲突怎么办

    1. **检查现有 key** - 确认是否真的冲突

    2. **使用更具体的路径** - 添加模块前缀区分

    3. **与项目成员协商** - 如果是公共 key 的修改,需沟通

    Q11: 如何处理部分国际化的遗留代码

    项目中可能存在部分已国际化但风格不一致的代码:

    1. **保持现有风格** - 不强制统一,避免大规模改动

    2. **新添加的遵循规范** - 新翻译使用规范写法

    3. **必要时可重构** - 如果发现明显问题,可提出建议

    Q12: 旧翻译 key 废弃怎么办

    1. **保留旧翻译** - 暂时保留,避免线上报错

    2. **标记废弃** - 添加注释说明已废弃

    3. **后续清理** - 定期清理未使用的废弃翻译

    Q13: 如何处理 slot 中的文字

    对于 scoped slot 中的静态文字:

    <!-- 转换前 -->
    <template #default="{ row }">
      <span>产品名称:{{ row.name }}</span>
    </template>
    
    <!-- 转换后 -->
    <template #default="{ row }">
      <span>{{ $t("product.name") }}:{{ row.name }}</span>
    </template>

    Q14: script 中如何使用翻译

    <script setup>
    // useI18n 通常由项目自动导入,无需手动 import
    // 如项目无自动导入,则需要:import { useI18n } from 'vue-i18n'
    
    const { t } = useI18n();
    
    // 在方法中使用
    function handleClick() {
      const message = t("common.message.success");
      ElMessage.success(message);
    }
    
    // 在计算属性中使用
    const statusText = computed(() => {
      return t(`product.status.${status.value}`);
    });
    </script>

    Q15: v-html 和 $t 结合使用需要注意什么

    **谨慎使用** `v-html`:

    <!-- 不推荐:可能有 XSS 风险 -->
    <span v-html="$t('message.withHtml')"></span>
    
    <!-- 推荐:分开处理 -->
    <span>{{ $t('message.prefix') }}<a :href="url">{{ $t('message.link') }}</a></span>

    如果必须使用 `v-html`,确保内容来自可信来源。

    Q16: 函数式组件中如何使用翻译

    对于使用 render 函数或 JSX 的组件:

    // 使用 this.$t(需要确保组件可访问到 i18n 实例)
    export default {
      render() {
        return h("span", this.$t("key.path"));
      },
    };
    
    // 或者通过 provide/inject 传递翻译函数
    // 父组件
    const { t } = useI18n();
    provide("i18n", { t });
    
    // 子组件
    const { t } = inject("i18n");
    return h("span", t("key.path"));

    Q17: keep-alive 缓存组件翻译切换问题

    使用 keep-alive 缓存的组件在切换语言后可能不会重新渲染:

    1. **监听语言变化** - 在 activated 生命周期中强制刷新

    <script setup>
    import { watch } from "vue";
    import { useI18n } from "vue-i18n";
    
    const { locale } = useI18n();
    
    // 监听语言变化,强制刷新
    watch(locale, () => {
      // 强制组件重新渲染
      refreshData();
    });
    </script>

    2. **使用 key 变化** - 为 keep-alive 组件添加 key

    <keep-alive>
      <component :is="component" :key="locale" />
    </keep-alive>

    Q18: 异步组件的翻译加载

    异步组件的翻译需要在主应用或单独加载:

    1. **如果项目使用全局翻译** - 异步组件会自动继承

    2. **如果需要单独加载** - 使用 vue-i18n 的懒加载功能

    // 懒加载翻译
    const messages = {
      en: () => import("./locales/en.json"),
      zh: () => import("./locales/zh.json"),
    };

    ---

    翻译准确性要求

    作为经验丰富的翻译专家,你需要遵循以下严格要求:

    1. 理解上下文语境

    翻译前必须理解文字的使用场景:

    | 场景 | 示例 | 翻译注意事项 |

    | ---------- | ---------------------------- | -------------------- |

    | 按钮文字 | "提交"、"确认"、"取消" | 简洁有力,通常用动词 |

    | 表单标签 | "产品名称"、"创建时间" | 名词短语,明确指示 |

    | 占位符 | "请输入名称"、"请选择日期" | 引导性语句 |

    | 提示信息 | "操作成功"、"保存失败" | 结果导向,说明状态 |

    | 对话框标题 | "新增产品"、"编辑品牌" | 动作 + 对象 |

    | 表格列 | "状态"、"创建人"、"更新时间" | 简洁名词 |

    2. 根据场景选择准确翻译

    同一个中文词在不同场景可能有不同译法:

    示例:中文 "状态"
    ├── 表格列标题 → "Status"
    ├── 业务流程中 → "State" 或 "Process Status"
    ├── 设备状态 → "Device Status"
    └── 订单状态 → "Order Status"
    
    示例:中文 "确认"
    ├── 按钮文字 → "Confirm" 或 "Submit"
    ├── 二次确认提示 → "Are you sure?"
    └── 确认框标题 → "Confirmation"
    
    示例:中文 "查看"
    ├── 表格操作列 → "View"
    ├── 查看详情 → "Details"
    ├── 查看记录 → "View Record"
    └── 查看图片 → "Preview"

    3. 保持翻译一致性

  • **相同含义 → 相同翻译**:整个项目中,相同含义的文字必须使用相同的翻译
  • **相同场景 → 相同模式**:类似场景使用类似的翻译结构和用词
  • **建立术语表**:对于专业术语,建立统一的翻译标准
  • ✅ 正确:所有"产品名称"都翻译为 "Product Name"
    ❌ 错误:有时翻译为 "Product Name",有时翻译为 "Name"

    4. 专业术语处理

  • **行业标准术语**:使用公认的英文术语
  • **产品特定术语**:保持与产品文档一致
  • **缩写和缩写词**:如需使用缩写,应在首次出现时提供全称
  • 示例:
    - SKU → Stock Keeping Unit(库存单位)
    - MDM → Master Data Management(主数据管理)
    - CRM → Customer Relationship Management(客户关系管理)

    5. key 命名规范

    遵循项目的命名规范,项目没有特殊规定时参考以下原则:

    命名原则:
    - 使用小写字母
    - 使用点分隔层级
    - 保持简洁但有意义
    - 避免缩写(除非是公认的缩写)
    
    层级结构建议:
    - 动作相关:{模块}.action.{具体动作}
      product.action.add, product.action.edit, product.action.delete
    
    - 字段相关:{模块}.{实体}.{字段名}
      product.product.name, product.product.code
    
    - 提示相关:{模块}.message.{类型}
      product.message.success, product.message.error
    
    - 占位符:common.placeholder.{类型}
      common.placeholder.input, common.placeholder.select
    
    公共部分:common.{类型}.{具体项}
      common.action.add, common.action.edit
      common.table.index, common.table.action
      common.message.success, common.message.error

    6. 长度和空间考虑

  • 英文翻译通常比中文短,但也要考虑UI空间
  • 避免过长的翻译导致布局问题
  • 必要时可以使用更简洁的表达
  • 7. 复数和单数

  • 注意英文的单复数形式
  • 根据实际场景选择单复数形式
  • 如果项目使用 vue-i18n 复数功能,按规范使用
  • 8. 大小写规范

  • 按钮文字:首字母大写(Save, Cancel, Confirm)
  • 表格列标题:首字母大写(Product Name, Status)
  • 占位符文字:首字母小写(please enter, please select)
  • 标题和标签:首字母大写
  • **遵循项目现有规范**
  • 9. 标点符号

  • 英文使用英文标点(, . 而不是 ,)
  • 但按钮文字、标签等通常不加句号
  • 提示信息根据语气决定是否加句号
  • ---

    翻译决策流程

    当遇到翻译时,按以下流程决策:

    1. 理解文字含义和用途
       ↓
    2. 查看项目现有翻译库
       ├── 已有相同翻译?→ 直接复用
       └── 没有?→ 继续
       ↓
    3. 分析使用场景
       ├── 什么类型的UI元素?
       ├── 在什么上下文中使用?
       └── 用户期望什么语气?
       ↓
    4. 选择最准确的翻译
       ↓
    5. 判断翻译放哪里
       ├── 通用性质?→ 公共目录
       └── 模块特有?→ 模块目录
       ↓
    6. 检查一致性
       ├── 是否与现有术语冲突?
       └── 是否需要更新术语表?

    ---

    注意事项

    1. **不修改项目结构** - 只在现有结构中添加内容,不创建新目录(除非项目本身就需要)

    2. **保持风格一致** - 使用项目现有的命名风格(camelCase, kebab-case, SCREAMING_SNAKE_CASE 等)

    3. **验证替换结果** - 修改后测试页面显示,确保没有破坏现有功能

    4. **公共翻译不放模块** - 通用性质的翻译不要放到模块目录中

    5. **模块翻译不放公共** - 特定业务模块的翻译不要放到公共目录中

    6. **所有语言同步** - 项目支持的所有语言都要同步更新

    7. **不破坏现有** - 所有修改基于现有规则,不改变现有结构

    ---

    验证与错误处理

    验证翻译质量

    修改完成后,必须验证:

    1. **语义准确性**:翻译是否准确表达原意?

    2. **场景合适性**:在当前场景下是否自然?

    3. **一致性检查**:类似文字是否使用类似翻译?

    4. **拼写和语法**:英文翻译是否有拼写错误或语法问题?

    5. **UI适配性**:翻译后是否超出UI空间?

    验证方法

    1. **运行时检查**:

    - 切换语言测试页面显示

    - 检查控制台是否有 missing translation 警告

    2. **代码检查**:

    - 搜索是否还有遗漏的硬编码

    - 确认所有 key 都已正确添加

    3. **如果项目有 lint 工具**:按项目规范执行

    错误处理

    1. **翻译错误**:

    - 立即修正错误翻译

    - 检查是否影响其他使用该翻译的地方

    2. **遗漏翻译**:

    - 补充遗漏的翻译

    - 检查是否还有其他遗漏

    3. **格式问题**:

    - 保持与项目现有格式一致

    - 使用项目的格式化工具(如果有)

    4. **如果出现问题**:

    - 使用 git 回滚到修改前

    - 检查问题原因后重新修改

    // Comments
    Sign in with GitHub to leave a comment.
    // Related skills

    More tools from the same signal band