国际化 (i18n)
Kupola 提供完整的国际化支持,内置英文(en-US)和中文(zh-CN)语言包,支持运行时动态切换语言。
快速开始
js
import { t, setLocale, getLocale } from '@kupola/platform/i18n'
// 设置语言
setLocale('zh-CN')
// 使用翻译
console.log(t('modal.close')) // '关闭'
// 切换回英文
setLocale('en-US')
console.log(t('modal.close')) // 'Close'API 参考
t(key, params)
翻译文本,支持参数插值。
js
// 基本翻译
t('dialog.ok') // 'OK'
// 参数插值
t('form.min', { min: 10 }) // 'Minimum value is 10'setLocale(locale)
设置当前语言,触发响应式更新。
js
setLocale('zh-CN')getLocale()
获取当前语言。
js
const locale = getLocale() // 'en-US'detectLocale()
自动检测浏览器语言,优先级:
- URL 参数
?lang= - localStorage
kupola-locale - 浏览器设置
navigator.language
js
const detected = detectLocale()addMessages(locale, messages)
添加自定义语言包。
js
// 添加日语支持
addMessages('ja-JP', {
'modal.close': '閉じる',
'dialog.ok': 'OK',
'dialog.cancel': 'キャンセル',
})
setLocale('ja-JP')getMessages(locale)
获取指定语言的消息对象。
js
const messages = getMessages('zh-CN')getSupportedLocales()
获取所有支持的语言列表。
js
const locales = getSupportedLocales() // ['en-US', 'zh-CN']formatDate(date, options)
格式化日期(基于 Intl API)。
js
import { formatDate } from '@kupola/platform/i18n'
const date = new Date(2024, 5, 15)
// 英文
setLocale('en-US')
formatDate(date, { year: 'numeric', month: 'long', day: 'numeric' })
// 'June 15, 2024'
// 中文
setLocale('zh-CN')
formatDate(date, { year: 'numeric', month: 'long', day: 'numeric' })
// '2024年6月15日'formatNumber(num, options)
格式化数字。
js
formatNumber(1234567.89)
// '1,234,567.89'formatCurrency(num, currency, options)
格式化货币。
js
formatCurrency(1234.56, 'USD') // '$1,234.56'
formatCurrency(1234.56, 'CNY') // '¥1,234.56'formatRelativeTime(value, unit, options)
格式化相对时间。
js
formatRelativeTime(-1, 'day') // '1 day ago'
formatRelativeTime(1, 'month') // 'in 1 month'
setLocale('zh-CN')
formatRelativeTime(-1, 'day') // '1天前'isRTL(locale)
判断是否为 RTL(从右到左)语言。
js
isRTL('ar') // true
isRTL('en-US') // falsegetDirection(locale)
获取文本方向。
js
getDirection('en-US') // 'ltr'
getDirection('ar') // 'rtl'onLocaleChange(callback)
监听语言变化事件。
js
const unsubscribe = onLocaleChange((newLocale, oldLocale) => {
console.log(`Language changed from ${oldLocale} to ${newLocale}`)
})
// 取消监听
unsubscribe()localeSignal
响应式 Signal,语言变化时自动触发 effect 更新。
js
import { effect } from '@kupola/core'
import { localeSignal, t } from '@kupola/platform/i18n'
effect(() => {
element.textContent = t('modal.close')
})
// 切换语言时,effect 自动重新执行
setLocale('zh-CN')内置翻译键名
通用
| 键名 | 英文 | 中文 |
|---|---|---|
modal.close | Close | 关闭 |
dialog.ok | OK | 确定 |
dialog.cancel | Cancel | 取消 |
table.empty | No data | 暂无数据 |
loading | Loading... | 加载中... |
error | Error | 错误 |
success | Success | 成功 |
warning | Warning | 警告 |
info | Info | 提示 |
表单
| 键名 | 英文 | 中文 |
|---|---|---|
form.required | This field is required | 此字段为必填项 |
form.email | Please enter a valid email | 请输入有效的邮箱地址 |
form.number | Please enter a valid number | 请输入有效的数字 |
form.min | Minimum value is | 最小值为 |
form.max | Maximum value is | 最大值为 |
操作
| 键名 | 英文 | 中文 |
|---|---|---|
submit | Submit | 提交 |
save | Save | 保存 |
delete | Delete | 删除 |
edit | Edit | 编辑 |
add | Add | 添加 |
confirm | Confirm | 确认 |
cancel | Cancel | 取消 |
分页
| 键名 | 英文 | 中文 |
|---|---|---|
pagination.page | Page | 页 |
pagination.of | of | / |
pageSize | Items per page | 每页条数 |
total | Total | 总计 |
完整翻译列表
Kupola 内置超过 300 个翻译键名,覆盖所有组件的用户可见文本。完整列表可通过 getMessages('en-US') 获取。
最佳实践
在组件中使用
js
import { defineComponent, html } from '@kupola/platform'
import { effect } from '@kupola/core'
import { t, localeSignal } from '@kupola/platform/i18n'
const MyComponent = defineComponent({
setup() {
const title = signal('')
effect(() => {
localeSignal.value // 依赖语言变化
title.value = t('modal.close')
})
return html`<div>${title}</div>`
}
})扩展自定义语言
js
// 创建自定义语言包文件
// locales/ja-JP.js
export const jaJP = {
'modal.close': '閉じる',
'dialog.ok': 'OK',
// ... 更多翻译
}
// 在应用入口注册
import { addMessages, setLocale } from '@kupola/platform/i18n'
import { jaJP } from './locales/ja-JP.js'
addMessages('ja-JP', jaJP)
setLocale('ja-JP')结合 CSS 方向
js
import { getDirection, onLocaleChange } from '@kupola/platform/i18n'
function applyDirection() {
document.documentElement.dir = getDirection()
}
applyDirection()
onLocaleChange(applyDirection)