国际化 (i18n)
YH-UI 提供了完善的国际化 (i18n) 支持,内置 67 种语言包,覆盖全球主流语言。你可以通过 YhConfigProvider 组件全局配置语言,也可以在组件内部使用 useLocale Hook 进行更细粒度的控制。
基础用法
通过 YhConfigProvider 的 locale 属性,你可以设置全局使用的语言包。如果不设置,默认使用简体中文 (zh-cn)。
March 2026
| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
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-cn | zhCn | 简体中文 |
| 繁体中文(台湾) | zh-tw | zhTw | 繁體中文 |
| 繁体中文(香港) | zh-hk | zhHk | 繁體中文 |
| 繁体中文(澳门) | zh-mo | zhMo | 繁體中文 |
东亚语言
| 语言 | 语言代码 | 导入名称 | 本地名称 |
|---|---|---|---|
| 日语 | ja | ja | 日本語 |
| 韩语 | ko | ko | 한국어 |
| 蒙古语 | mn | mn | Монгол |
东南亚语言
| 语言 | 语言代码 | 导入名称 | 本地名称 |
|---|---|---|---|
| 泰语 | th | th | ไทย |
| 越南语 | vi | vi | Tiếng Việt |
| 印度尼西亚语 | id | id | Bahasa Indonesia |
| 马来语 | ms | ms | Bahasa Melayu |
| 缅甸语 | my | my | မြန်မာ |
| 高棉语(柬埔寨) | km | km | ខ្មែរ |
| 老挝语 | lo | lo | ລາວ |
南亚语言
| 语言 | 语言代码 | 导入名称 | 本地名称 |
|---|---|---|---|
| 印地语 | hi | hi | हिन्दी |
| 旁遮普语 | pa | pa | ਪੰਜਾਬੀ |
| 孟加拉语 | bn | bn | বাংলা |
| 泰米尔语 | ta | ta | தமிழ் |
| 泰卢固语 | te | te | తెలుగు |
西欧语言
| 语言 | 语言代码 | 导入名称 | 本地名称 |
|---|---|---|---|
| 英语 | en | en | English |
| 德语 | de | de | Deutsch |
| 法语 | fr | fr | Français |
| 西班牙语 | es | es | Español |
| 葡萄牙语 | pt | pt | Português |
| 葡萄牙语(巴西) | pt-br | ptBr | Português (Brasil) |
| 意大利语 | it | it | Italiano |
| 荷兰语 | nl | nl | Nederlands |
| 加泰罗尼亚语 | ca | ca | Català |
| 巴斯克语 | eu | eu | Euskara |
北欧语言
| 语言 | 语言代码 | 导入名称 | 本地名称 |
|---|---|---|---|
| 丹麦语 | da | da | Dansk |
| 瑞典语 | sv | sv | Svenska |
| 芬兰语 | fi | fi | Suomi |
| 挪威语 | no | no | Norsk |
| 挪威语(书面) | nb-NO | nbNo | Norsk Bokmål |
东欧语言
| 语言 | 语言代码 | 导入名称 | 本地名称 |
|---|---|---|---|
| 俄语 | ru | ru | Русский |
| 乌克兰语 | uk | uk | Українська |
| 波兰语 | pl | pl | Polski |
| 捷克语 | cs | cs | Čeština |
| 斯洛伐克语 | sk | sk | Slovenčina |
| 匈牙利语 | hu | hu | Magyar |
| 罗马尼亚语 | ro | ro | Română |
| 保加利亚语 | bg | bg | Български |
| 塞尔维亚语 | sr | sr | Српски |
| 克罗地亚语 | hr | hr | Hrvatski |
| 斯洛文尼亚语 | sl | sl | Slovenščina |
| 爱沙尼亚语 | et | et | Eesti |
| 拉脱维亚语 | lv | lv | Latviešu |
| 立陶宛语 | lt | lt | Lietuvių |
中东/西亚语言
| 语言 | 语言代码 | 导入名称 | 本地名称 |
|---|---|---|---|
| 阿拉伯语 | ar | ar | العربية |
| 阿拉伯语(埃及) | ar-eg | arEg | العربية (مصر) |
| 土耳其语 | tr | tr | Türkçe |
| 波斯语 | fa | fa | فارسی |
| 希伯来语 | he | he | עברית |
| 亚美尼亚语 | hy-am | hyAm | Հայերեն |
| 阿塞拜疆语 | az | az | Azərbaycan |
| 希腊语 | el | el | Ελληνικά |
中亚语言
| 语言 | 语言代码 | 导入名称 | 本地名称 |
|---|---|---|---|
| 哈萨克语 | kk | kk | Қазақша |
| 吉尔吉斯语 | ky | ky | Кыргызча |
| 土库曼语 | tk | tk | Türkmen |
| 乌兹别克语 | uz-uz | uzUz | O'zbekcha |
| 维吾尔语 | ug-cn | ugCn | ئۇيغۇرچە |
| 库尔德语(北) | ku | ku | Kurdî |
| 库尔德语(中) | ckb | ckb | کوردی |
非洲语言
| 语言 | 语言代码 | 导入名称 | 本地名称 |
|---|---|---|---|
| 阿非利卡语 | af | af | Afrikaans |
| 斯瓦希里语 | sw | sw | Kiswahili |
| 马达加斯加语 | mg | mg | Malagasy |
人工语言
| 语言 | 语言代码 | 导入名称 | 本地名称 |
|---|---|---|---|
| 世界语 | eo | eo | Esperanto |
导入示例:
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 返回值
| 属性/方法 | 类型 | 说明 |
|---|---|---|
locale | ComputedRef<Language> | 当前语言包对象 |
lang | ComputedRef<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: '第四季度'
}
}其他组件
点击展开完整的组件翻译键列表
| 组件 | 命名空间 | 主要翻译键 |
|---|---|---|
| 时间选择器 | timepicker | confirm, cancel, now, placeholder, startPlaceholder, endPlaceholder |
| 时间选择 | timeselect | placeholder |
| 日历 | calendar | prevMonth, nextMonth, today, week, holiday, workday, weeks.* |
| 选择器 | select | placeholder, noData, loading, noMatch, selectAll, clearAll |
| 级联选择 | cascader | placeholder, noData, loading, noMatch |
| 树选择 | treeselect | placeholder, emptyText, loading, noMatch |
| 穿梭框 | transfer | titles, filterPlaceholder, noData, noMatch, noCheckedFormat, hasCheckedFormat |
| 输入框 | input | placeholder, clear, showPassword, hidePassword, copy, copied |
| 数字输入框 | inputnumber | placeholder, increase, decrease |
| 标签输入 | inputtag | placeholder, add, remove |
| 自动完成 | autocomplete | placeholder, loading, noData, noMatch |
| 上传 | upload | tip, dragTip, uploading, success, error, delete, preview |
| 表单 | form | validationFailed, required, pleaseInput, pleaseSelect |
| 分页 | pagination | goto, page, total, pageSize, prev, next, first, last |
| 对话框 | dialog | confirm, cancel, close, maximize, restore |
| 抽屉 | drawer | close, confirm, cancel |
| 消息框 | messagebox | title, confirm, cancel, close, error |
| 消息 | message | close |
| 通知 | notification | close |
| 气泡确认 | popconfirm | confirm, cancel, dontAskAgain |
| 图片 | image | error, loading, preview, zoomIn, zoomOut, rotateLeft, rotateRight |
| 无限滚动 | infinitescroll | loading, finished, error, retry |
| 树 | tree | emptyText, loading, checkAll, uncheckAll, expandAll, collapseAll |
| 颜色选择器 | colorpicker | confirm, clear, eyeDropper, suggestionDark, suggestionLight |
| 评分 | rate | texts (数组) |
| 倒计时 | countdown | days, hours, minutes, seconds, milliseconds, finished |
| 加载 | spin | text |
| 按钮 | button | loading |
| 面包屑 | breadcrumb | label, more |
| 返回顶部 | backtop | text |
| 下拉菜单 | dropdown | loading |
| 空状态 | empty | description, noData, noResult, networkError, serverError |
| 结果 | result | success, 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.ts 和 en.ts 实现。
贡献步骤
- Fork 仓库
- 在
packages/locale/src/lang目录下创建新的语言文件(如new-lang.ts) - 参考
zh-cn.ts的结构完成所有翻译 - 在
packages/locale/src/index.ts中导出新的语言包 - 提交 Pull Request
常见问题
为什么某些组件的文本没有被翻译?
请确保:
- 已正确使用
YhConfigProvider包裹应用 - 传入的
locale属性是响应式的(使用ref或computed) - 语言包中包含对应的翻译键
如何只翻译部分组件?
你可以在特定区域使用嵌套的 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 条'