Skip to content

国际化 (i18n)

YH-UI 提供了完善的国际化 (i18n) 支持,内置 67 种语言包,覆盖全球主流语言。你可以通过 YhConfigProvider 组件全局配置语言,也可以在组件内部使用 useLocale Hook 进行更细粒度的控制。

基础用法

通过 YhConfigProviderlocale 属性,你可以设置全局使用的语言包。如果不设置,默认使用简体中文 (zh-cn)。

March 2026
SunMonTueWedThuFriSat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
基础用法

多语言切换

YH-UI 内置了 67 种语言包,你可以通过下拉选择器动态切换任意语言。

zh-cn
当前语言: zh-cn
2026年3月
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
多语言切换

内置语言包

YH-UI 内置了 67 种语言包,覆盖全球主要语言和地区:

中文

语言语言代码导入名称本地名称
简体中文zh-cnzhCn简体中文
繁体中文(台湾)zh-twzhTw繁體中文
繁体中文(香港)zh-hkzhHk繁體中文
繁体中文(澳门)zh-mozhMo繁體中文

东亚语言

语言语言代码导入名称本地名称
日语jaja日本語
韩语koko한국어
蒙古语mnmnМонгол

东南亚语言

语言语言代码导入名称本地名称
泰语ththไทย
越南语viviTiếng Việt
印度尼西亚语ididBahasa Indonesia
马来语msmsBahasa Melayu
缅甸语mymyမြန်မာ
高棉语(柬埔寨)kmkmខ្មែរ
老挝语loloລາວ

南亚语言

语言语言代码导入名称本地名称
印地语hihiहिन्दी
旁遮普语papaਪੰਜਾਬੀ
孟加拉语bnbnবাংলা
泰米尔语tataதமிழ்
泰卢固语teteతెలుగు

西欧语言

语言语言代码导入名称本地名称
英语enenEnglish
德语dedeDeutsch
法语frfrFrançais
西班牙语esesEspañol
葡萄牙语ptptPortuguês
葡萄牙语(巴西)pt-brptBrPortuguês (Brasil)
意大利语ititItaliano
荷兰语nlnlNederlands
加泰罗尼亚语cacaCatalà
巴斯克语eueuEuskara

北欧语言

语言语言代码导入名称本地名称
丹麦语dadaDansk
瑞典语svsvSvenska
芬兰语fifiSuomi
挪威语nonoNorsk
挪威语(书面)nb-NOnbNoNorsk Bokmål

东欧语言

语言语言代码导入名称本地名称
俄语ruruРусский
乌克兰语ukukУкраїнська
波兰语plplPolski
捷克语cscsČeština
斯洛伐克语skskSlovenčina
匈牙利语huhuMagyar
罗马尼亚语roroRomână
保加利亚语bgbgБългарски
塞尔维亚语srsrСрпски
克罗地亚语hrhrHrvatski
斯洛文尼亚语slslSlovenščina
爱沙尼亚语etetEesti
拉脱维亚语lvlvLatviešu
立陶宛语ltltLietuvių

中东/西亚语言

语言语言代码导入名称本地名称
阿拉伯语ararالعربية
阿拉伯语(埃及)ar-egarEgالعربية (مصر)
土耳其语trtrTürkçe
波斯语fafaفارسی
希伯来语heheעברית
亚美尼亚语hy-amhyAmՀայերեն
阿塞拜疆语azazAzərbaycan
希腊语elelΕλληνικά

中亚语言

语言语言代码导入名称本地名称
哈萨克语kkkkҚазақша
吉尔吉斯语kykyКыргызча
土库曼语tktkTürkmen
乌兹别克语uz-uzuzUzO'zbekcha
维吾尔语ug-cnugCnئۇيغۇرچە
库尔德语(北)kukuKurdî
库尔德语(中)ckbckbکوردی

非洲语言

语言语言代码导入名称本地名称
阿非利卡语afafAfrikaans
斯瓦希里语swswKiswahili
马达加斯加语mgmgMalagasy

人工语言

语言语言代码导入名称本地名称
世界语eoeoEsperanto

导入示例:

ts
// 导入单个语言包
import { zhCn, en, ja, ko, fr, de } from '@yh-ui/locale'

// 导入所有语言包
import * as locales from '@yh-ui/locale'

全局配置

在 Vue 3 中使用

在应用入口处使用 YhConfigProvider 包裹根组件:

vue
<!-- App.vue -->
<script setup lang="ts">
import { ref } from 'vue'
import { en, zhCn } from '@yh-ui/locale'

// 可以根据用户偏好或浏览器语言动态设置
const locale = ref(zhCn)
</script>

<template>
  <YhConfigProvider :locale="locale">
    <router-view />
  </YhConfigProvider>
</template>

在 Nuxt 3 中使用

app.vue 中配置:

vue
<!-- app.vue -->
<script setup lang="ts">
import { zhCn } from '@yh-ui/locale'
</script>

<template>
  <YhConfigProvider :locale="zhCn">
    <NuxtPage />
  </YhConfigProvider>
</template>

动态切换语言

vue
<script setup lang="ts">
import { ref, computed } from 'vue'
import { zhCn, en, ja, ko, fr, de } from '@yh-ui/locale'

// 语言映射表
const localeMap = {
  'zh-cn': zhCn,
  'en': en,
  'ja': ja,
  'ko': ko,
  'fr': fr,
  'de': de
}

const currentLang = ref('zh-cn')
const currentLocale = computed(() => localeMap[currentLang.value] || zhCn)

// 切换语言
const switchLanguage = (lang: string) => {
  currentLang.value = lang
}

// 根据浏览器语言自动设置
const autoDetectLanguage = () => {
  const browserLang = navigator.language.toLowerCase()
  if (browserLang.startsWith('zh')) {
    currentLang.value = 'zh-cn'
  } else if (browserLang.startsWith('ja')) {
    currentLang.value = 'ja'
  } else if (browserLang.startsWith('ko')) {
    currentLang.value = 'ko'
  } else {
    currentLang.value = 'en'
  }
}
</script>

<template>
  <YhConfigProvider :locale="currentLocale">
    <div>
      <select v-model="currentLang">
        <option value="zh-cn">中文</option>
        <option value="en">English</option>
        <option value="ja">日本語</option>
        <option value="ko">한국어</option>
        <option value="fr">Français</option>
        <option value="de">Deutsch</option>
      </select>
    </div>
    <!-- 你的应用内容 -->
  </YhConfigProvider>
</template>

使用 useLocale Hook

在组件内部,你可以使用 useLocale Hook 来获取翻译函数和当前语言信息:

vue
<script setup lang="ts">
import { useLocale } from '@yh-ui/hooks'

const { t, tRaw, lang, locale } = useLocale()

// 获取字符串翻译
const emptyText = t('table.emptyText') // '暂无数据'

// 带插值的翻译
const totalText = t('pagination.total', { total: 100 }) // '共 100 条'

// 获取非字符串类型的翻译(如数组)
const rateTexts = tRaw<string[]>('rate.texts') // ['极差', '失望', '一般', '满意', '惊喜']

// 当前语言名称
console.log(lang.value) // 'zh-cn' 或 'en'
</script>

useLocale 返回值

属性/方法类型说明
localeComputedRef<Language>当前语言包对象
langComputedRef<string>当前语言名称,如 'zh-cn''en'
t(path: string, options?: Record<string, string | number>) => string翻译函数,支持插值
tRaw<T>(path: string) => T获取原始翻译值,支持数组等非字符串类型

自定义翻译

覆盖部分翻译

你可以通过扩展现有语言包来修改或补充某些翻译项:

ts
import { zhCn } from '@yh-ui/locale'
import type { Language } from '@yh-ui/locale'

const customZhCn: Language = {
  ...zhCn,
  yh: {
    ...zhCn.yh,
    table: {
      ...zhCn.yh.table,
      emptyText: '这里空空如也~',
      loading: '数据加载中,请稍候...'
    },
    pagination: {
      ...zhCn.yh.pagination,
      total: '共计 {total} 条记录'
    }
  }
}

创建新的语言包

如果需要支持其他语言,可以参考现有语言包的结构创建:

ts
import type { Language } from '@yh-ui/locale'

export const myLang: Language = {
  name: 'my-lang',
  yh: {
    common: {
      yes: 'Yes',
      no: 'No',
      confirm: 'Confirm',
      cancel: 'Cancel',
      loading: 'Loading',
      close: 'Close',
      clear: 'Clear',
      reset: 'Reset',
      save: 'Save',
      delete: 'Delete',
      edit: 'Edit',
      add: 'Add',
      search: 'Search',
      refresh: 'Refresh',
      expand: 'Expand',
      collapse: 'Collapse',
      more: 'More',
      noData: 'No Data',
      noMatch: 'No matching data',
      selectAll: 'Select All',
      unselectAll: 'Unselect All'
    },
    // ... 其他组件的翻译
  }
}

语言包结构

YH-UI 的语言包采用扁平化的命名空间结构,每个组件都有独立的翻译键。以下是完整的语言包结构:

通用 (common)

ts
common: {
  yes: '是',
  no: '否',
  confirm: '确认',
  cancel: '取消',
  loading: '加载中',
  close: '关闭',
  clear: '清空',
  reset: '重置',
  save: '保存',
  delete: '删除',
  edit: '编辑',
  add: '新增',
  search: '搜索',
  refresh: '刷新',
  expand: '展开',
  collapse: '收起',
  more: '更多',
  noData: '暂无数据',
  noMatch: '无匹配数据',
  selectAll: '全选',
  unselectAll: '取消全选'
}

表格 (table)

ts
table: {
  emptyText: '暂无数据',
  confirmFilter: '筛选',
  resetFilter: '重置',
  clearFilter: '全部',
  sumText: '合计',
  loading: '正在加载...',
  index: '序号',
  print: '打 印',
  cancel: '取 消',
  preview: '打印预览',
  printTime: '打印时间',
  total: '共 {total} 条',
  page: '第 {page} 页',
  yes: '是',
  no: '否',
  // 工具栏
  toolbar: {
    refresh: '刷新',
    density: '密度',
    densityDefault: '默认',
    densityLarge: '宽松',
    densitySmall: '紧凑',
    columnSetting: '列设置',
    fullscreen: '全屏',
    exitFullscreen: '退出全屏',
    export: '导出',
    import: '导入',
    search: '搜索',
    searchPlaceholder: '请输入关键词搜索'
  },
  // 筛选
  filter: {
    selectAll: '全选',
    selectInvert: '反选',
    empty: '为空',
    notEmpty: '不为空',
    contains: '包含',
    notContains: '不包含',
    equals: '等于',
    notEquals: '不等于',
    startsWith: '开头是',
    endsWith: '结尾是',
    greaterThan: '大于',
    lessThan: '小于',
    between: '介于'
  },
  // 排序
  sort: {
    asc: '升序',
    desc: '降序',
    clear: '取消排序'
  },
  // 导出
  export: {
    title: '导出数据',
    filename: '文件名',
    type: '文件类型',
    scope: '导出范围',
    scopeAll: '全部数据',
    scopeSelected: '选中数据',
    scopeCurrentPage: '当前页数据',
    includeHeader: '包含表头',
    exporting: '正在导出...',
    success: '导出成功',
    error: '导出失败'
  },
  // 导入
  import: {
    title: '导入数据',
    selectFile: '选择文件',
    dragTip: '点击或拖拽文件到此处上传',
    importing: '正在导入...',
    success: '导入成功',
    error: '导入失败',
    preview: '数据预览',
    confirm: '确认导入'
  },
  // 打印配置
  printConfig: {
    title: '打印设置',
    pageTitle: '页面标题',
    pageHeader: '页眉',
    pageFooter: '页脚',
    printAll: '打印全部',
    printSelected: '打印选中',
    printCurrentPage: '打印当前页',
    landscape: '横向',
    portrait: '纵向',
    printing: '正在打印...'
  },
  // 列设置
  columnSetting: {
    title: '列设置',
    showAll: '显示全部',
    hideAll: '隐藏全部',
    reset: '重置',
    fixedLeft: '固定在左侧',
    fixedRight: '固定在右侧',
    unfixed: '取消固定'
  },
  // 右键菜单
  contextMenu: {
    copy: '复制',
    copyRow: '复制行',
    copyCell: '复制单元格',
    paste: '粘贴',
    insertRowAbove: '在上方插入行',
    insertRowBelow: '在下方插入行',
    deleteRow: '删除行',
    deleteSelectedRows: '删除选中行',
    exportSelected: '导出选中数据'
  },
  // 选择
  selection: {
    selectAll: '全选',
    selectInvert: '反选',
    selectNone: '取消选择',
    selected: '已选择 {count} 项'
  },
  // 展开
  expand: {
    expandAll: '展开全部',
    collapseAll: '收起全部'
  },
  // 树形
  tree: {
    expandAll: '展开全部',
    collapseAll: '收起全部',
    expandLevel: '展开到第 {level} 层'
  },
  // 拖拽
  drag: {
    dragTip: '拖拽以调整顺序',
    dropTip: '释放以放置'
  }
}

日期选择器 (datepicker)

ts
datepicker: {
  now: '此刻',
  today: '今天',
  cancel: '取消',
  clear: '清空',
  confirm: '确定',
  selectDate: '选择日期',
  selectTime: '选择时间',
  startDate: '开始日期',
  startTime: '开始时间',
  endDate: '结束日期',
  endTime: '结束时间',
  year: '年',
  month: '月',
  day: '日',
  week: '周',
  prevYear: '上一年',
  nextYear: '下一年',
  prevMonth: '上个月',
  nextMonth: '下个月',
  weeks: {
    sun: '日', mon: '一', tue: '二', wed: '三',
    thu: '四', fri: '五', sat: '六'
  },
  months: {
    jan: '一月', feb: '二月', mar: '三月', apr: '四月',
    may: '五月', jun: '六月', jul: '七月', aug: '八月',
    sep: '九月', oct: '十月', nov: '十一月', dec: '十二月'
  },
  quarters: {
    q1: '第一季度', q2: '第二季度', q3: '第三季度', q4: '第四季度'
  }
}

其他组件

点击展开完整的组件翻译键列表
组件命名空间主要翻译键
时间选择器timepickerconfirm, cancel, now, placeholder, startPlaceholder, endPlaceholder
时间选择timeselectplaceholder
日历calendarprevMonth, nextMonth, today, week, holiday, workday, weeks.*
选择器selectplaceholder, noData, loading, noMatch, selectAll, clearAll
级联选择cascaderplaceholder, noData, loading, noMatch
树选择treeselectplaceholder, emptyText, loading, noMatch
穿梭框transfertitles, filterPlaceholder, noData, noMatch, noCheckedFormat, hasCheckedFormat
输入框inputplaceholder, clear, showPassword, hidePassword, copy, copied
数字输入框inputnumberplaceholder, increase, decrease
标签输入inputtagplaceholder, add, remove
自动完成autocompleteplaceholder, loading, noData, noMatch
上传uploadtip, dragTip, uploading, success, error, delete, preview
表单formvalidationFailed, required, pleaseInput, pleaseSelect
分页paginationgoto, page, total, pageSize, prev, next, first, last
对话框dialogconfirm, cancel, close, maximize, restore
抽屉drawerclose, confirm, cancel
消息框messageboxtitle, confirm, cancel, close, error
消息messageclose
通知notificationclose
气泡确认popconfirmconfirm, cancel, dontAskAgain
图片imageerror, loading, preview, zoomIn, zoomOut, rotateLeft, rotateRight
无限滚动infinitescrollloading, finished, error, retry
treeemptyText, loading, checkAll, uncheckAll, expandAll, collapseAll
颜色选择器colorpickerconfirm, clear, eyeDropper, suggestionDark, suggestionLight
评分ratetexts (数组)
倒计时countdowndays, hours, minutes, seconds, milliseconds, finished
加载spintext
按钮buttonloading
面包屑breadcrumblabel, more
返回顶部backtoptext
下拉菜单dropdownloading
空状态emptydescription, noData, noResult, networkError, serverError
结果resultsuccess, error, warning, info, backHome

与第三方 i18n 库集成

与 vue-i18n 集成

如果你的项目使用 vue-i18n,可以将 YH-UI 的语言包合并到 vue-i18n 中:

ts
import { createI18n } from 'vue-i18n'
import { zhCn, en } from '@yh-ui/locale'

const i18n = createI18n({
  locale: 'zh-cn',
  messages: {
    'zh-cn': {
      // 你的业务翻译
      hello: '你好',
      // 合并 YH-UI 翻译
      yh: zhCn.yh
    },
    'en': {
      hello: 'Hello',
      yh: en.yh
    }
  }
})

然后创建一个响应式的语言包:

ts
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import type { Language } from '@yh-ui/locale'

export function useYhLocale() {
  const { locale, messages } = useI18n()
  
  return computed<Language>(() => ({
    name: locale.value,
    yh: messages.value[locale.value].yh
  }))
}

TypeScript 支持

YH-UI 的语言包提供了完整的 TypeScript 类型定义。你可以导入 Language 类型来获得类型提示:

ts
import type { Language } from '@yh-ui/locale'

// 创建自定义语言包时会有完整的类型提示
const customLocale: Language = {
  name: 'custom',
  yh: {
    // TypeScript 会提示所有必需的属性
  }
}

贡献翻译

如果你发现翻译有误或希望增加新的语言支持,欢迎提交 Pull Request

语言包文件位于 packages/locale/src/lang 目录下,你可以参考现有的 zh-cn.tsen.ts 实现。

贡献步骤

  1. Fork 仓库
  2. packages/locale/src/lang 目录下创建新的语言文件(如 new-lang.ts
  3. 参考 zh-cn.ts 的结构完成所有翻译
  4. packages/locale/src/index.ts 中导出新的语言包
  5. 提交 Pull Request

常见问题

为什么某些组件的文本没有被翻译?

请确保:

  1. 已正确使用 YhConfigProvider 包裹应用
  2. 传入的 locale 属性是响应式的(使用 refcomputed
  3. 语言包中包含对应的翻译键

如何只翻译部分组件?

你可以在特定区域使用嵌套的 YhConfigProvider

vue
<template>
  <YhConfigProvider :locale="zhCn">
    <!-- 这里使用中文 -->
    <YhTable />
    
    <YhConfigProvider :locale="en">
      <!-- 这里使用英文 -->
      <YhPagination />
    </YhConfigProvider>
  </YhConfigProvider>
</template>

翻译中的插值变量如何使用?

某些翻译包含插值变量(如 {total}{count}),这些会在运行时被替换:

ts
// 语言包定义
pagination: {
  total: '共 {total} 条'
}

// 组件内部使用
t('pagination.total', { total: 100 }) // 输出: '共 100 条'

Released under the MIT License.