Skip to content

国际化与通用配置

项目使用 Vue I18n 提供中文和英文切换,并将用户语言偏好、站点默认语言和 Element Plus 交互文案连接为一套完整流程。国际化不只是翻译页面文字,还包括默认语言优先级、组件库文案和页面标题同步。

目录结构

text
src/locales/
├── index.ts
└── langs/
    ├── zh.json
    └── en.json

src/plugins/element-plus.ts
src/store/modules/user.ts
src/store/modules/site-settings.ts

当前支持:

语言标识语言包
简体中文zhsrc/locales/langs/zh.json
Englishensrc/locales/langs/en.json

fallbackLocale 固定为中文。当英文语言包缺少键时,会回退显示中文内容,避免直接显示翻译键。

启动时的语言优先级

语言选择遵循以下顺序:

text
用户已经保存的语言偏好
  -> 有:直接使用
  -> 无:先以中文启动
       -> 异步加载站点公共配置
       -> 未登录用户采用 defaultLanguage

这意味着:

  • 用户主动选择过语言后,个人偏好优先于站点默认值。
  • 没有个人偏好时,应用先稳定以中文挂载,不阻塞首屏。
  • 公共站点配置加载完成后,未登录用户再应用 defaultLanguage
  • 已登录用户不会被站点默认语言覆盖。

在模板中使用

Vue I18n 已启用全局注入:

vue
<template>
  <ElButton>{{ $t('common.confirm') }}</ElButton>
</template>

动态参数:

json
{
  "order": {
    "count": "共 {count} 条订单"
  }
}
vue
<span>{{ $t('order.count', { count: total }) }}</span>

在 TypeScript 中使用

项目导出全局 $t

ts
import { $t } from '@/locales'

ElMessage.success($t('common.saveSuccess'))

需要监听当前语言或在组合式逻辑中处理复数规则时,可以使用 useI18n()

ts
import { useI18n } from 'vue-i18n'

const { t, locale } = useI18n()

纯展示文案优先直接使用 $t,需要响应语言变化的计算逻辑再使用组合式 API。

添加新文案

中文和英文语言包应保持相同结构:

json
// zh.json
{
  "customer": {
    "title": "客户管理",
    "create": "新建客户"
  }
}
json
// en.json
{
  "customer": {
    "title": "Customers",
    "create": "Create customer"
  }
}

命名建议:

  • 按业务域分组,例如 customerorderworkflow
  • 通用操作放在 common,避免每个模块重复维护“确认”“取消”。
  • 键名描述语义,不使用页面上的最终中文作为键。
  • 不把整段 HTML 写入语言包。
  • 插值参数使用明确名称,例如 {count}{name}

切换语言

语言由 userStore.setLanguage() 统一修改:

ts
import { LanguageEnum } from '@/enums/appEnum'
import { useUserStore } from '@/store/modules/user'

const userStore = useUserStore()
userStore.setLanguage(LanguageEnum.EN)

该方法会同步:

  • Vue I18n 当前 locale
  • 用户持久化偏好
  • 当前路由页面标题

不要只修改 i18n.global.locale,否则可能绕过项目已有的持久化和标题更新流程。

Element Plus 文案

src/plugins/element-plus.tsElMessageBoxalertconfirmprompt 注入当前语言下的默认按钮:

text
中文:确认 / 取消
英文:OK / Cancel

业务页面仍可以显式覆盖:

ts
ElMessageBox.confirm(message, title, {
  confirmButtonText: $t('order.forceSubmit')
})

只有业务语义明确不同于通用“确认”时才覆盖,避免同一系统出现多套无规律按钮文案。

站点公共配置

站点默认语言来自公共配置 defaultLanguage。它主要影响没有明确个人偏好的未登录用户,例如登录页和公开页面。

品牌名称、Logo、版权信息等站点级配置也应通过 site-settings 统一读取,避免在页面组件中硬编码。对于纯前端交付中的本地实现,客户接入后端后可以保持相同 Store 入口,只替换数据来源。

日期、数字与接口值

界面文案国际化不等于接口枚举国际化:

  • 后端状态值保持稳定代码,例如 pendingapproved
  • 前端根据状态代码映射翻译键。
  • 日期和数字展示统一经过格式化函数。
  • 不把中文状态直接作为权限码、路由名或数据库枚举。
ts
const statusLabelMap = {
  pending: 'order.status.pending',
  approved: 'order.status.approved'
} as const

检查清单

  • 新增页面同时补齐中英文键。
  • 切换语言后页面标题和 MessageBox 按钮同步变化。
  • 未登录且无偏好时,站点默认语言生效。
  • 已保存的用户偏好不会被公共配置覆盖。
  • 不在语言包中存储业务数据或 HTML。
  • 缺失翻译时中文回退内容仍然可理解。

主题与站点配置见布局、主题与配置,持久化原理见状态管理

根据 MIT 许可证发布