Skip to content

国际化

Speed UI 内置了完整的国际化(i18n)支持,让你的应用能够轻松适配多种语言和地区。

默认语言

Speed UI 默认使用中文(简体),但你可以轻松切换到其他语言。

支持的语言

目前 Speed UI 支持以下语言:

  • 🇨🇳 中文(简体)- zh-CN
  • 🇭🇰 中文(繁体)- zh-TW
  • 🇺🇸 英语 - en-US
  • 🇯🇵 日语 - ja-JP
  • 🇰🇷 韩语 - ko-KR
  • 🇩🇪 德语 - de-DE
  • 🇫🇷 法语 - fr-FR
  • 🇪🇸 西班牙语 - es-ES
  • 🇮🇹 意大利语 - it-IT
  • 🇷🇺 俄语 - ru-RU

快速开始

全局配置

typescript
// main.ts
import { createApp } from 'vue'
import SpeedUI from 'speed-ui-vue'
import 'speed-ui-vue/styles'

// 导入语言包
import zhCN from 'speed-ui-vue/locale/zh-CN'
import enUS from 'speed-ui-vue/locale/en-US'

import App from './App.vue'

const app = createApp(App)

// 配置默认语言
app.use(SpeedUI, {
  locale: zhCN // 或 enUS
})

app.mount('#app')

按需引入时的配置

typescript
// main.ts
import { createApp } from 'vue'
import { ConfigProvider } from 'speed-ui-vue'
import zhCN from 'speed-ui-vue/locale/zh-CN'

import App from './App.vue'

const app = createApp(App)
app.mount('#app')
vue
<!-- App.vue -->
<template>
  <sp-config-provider :locale="locale">
    <router-view />
  </sp-config-provider>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import zhCN from 'speed-ui-vue/locale/zh-CN'

const locale = ref(zhCN)
</script>

动态切换语言

使用 ConfigProvider

vue
<template>
  <div>
    <sp-select v-model="currentLocale" @change="handleLocaleChange">
      <sp-option value="zh-CN">中文</sp-option>
      <sp-option value="en-US">English</sp-option>
      <sp-option value="ja-JP">日本語</sp-option>
    </sp-select>
    
    <sp-config-provider :locale="locale">
      <sp-date-picker />
      <sp-pagination :total="100" />
      <sp-empty description="暂无数据" />
    </sp-config-provider>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import zhCN from 'speed-ui-vue/locale/zh-CN'
import enUS from 'speed-ui-vue/locale/en-US'
import jaJP from 'speed-ui-vue/locale/ja-JP'

const currentLocale = ref('zh-CN')

const localeMap = {
  'zh-CN': zhCN,
  'en-US': enUS,
  'ja-JP': jaJP
}

const locale = computed(() => localeMap[currentLocale.value])

const handleLocaleChange = (value: string) => {
  currentLocale.value = value
}
</script>

使用组合式函数

创建一个全局的语言管理组合式函数:

typescript
// composables/useLocale.ts
import { ref, computed } from 'vue'
import type { Locale } from 'speed-ui-vue'

import zhCN from 'speed-ui-vue/locale/zh-CN'
import enUS from 'speed-ui-vue/locale/en-US'
import jaJP from 'speed-ui-vue/locale/ja-JP'

export type SupportedLocale = 'zh-CN' | 'en-US' | 'ja-JP'

const currentLocale = ref<SupportedLocale>('zh-CN')

const localeMap: Record<SupportedLocale, Locale> = {
  'zh-CN': zhCN,
  'en-US': enUS,
  'ja-JP': jaJP
}

export const useLocale = () => {
  const locale = computed(() => localeMap[currentLocale.value])
  
  const setLocale = (newLocale: SupportedLocale) => {
    currentLocale.value = newLocale
    // 可以在这里添加持久化逻辑
    localStorage.setItem('speed-ui-locale', newLocale)
  }
  
  const getLocaleText = (key: string) => {
    return locale.value[key] || key
  }
  
  // 初始化时从 localStorage 读取
  const savedLocale = localStorage.getItem('speed-ui-locale') as SupportedLocale
  if (savedLocale && localeMap[savedLocale]) {
    currentLocale.value = savedLocale
  }
  
  return {
    currentLocale,
    locale,
    setLocale,
    getLocaleText
  }
}

自定义语言包

创建自定义语言包

typescript
// locale/my-locale.ts
import type { Locale } from 'speed-ui-vue'

const myLocale: Locale = {
  name: 'my-locale',
  common: {
    confirm: '确认',
    cancel: '取消',
    clear: '清除',
    loading: '加载中...',
    noData: '暂无数据',
    placeholder: '请输入',
    selectPlaceholder: '请选择'
  },
  datePicker: {
    selectDate: '选择日期',
    selectTime: '选择时间',
    startDate: '开始日期',
    endDate: '结束日期',
    clear: '清除',
    confirm: '确认',
    today: '今天',
    month: '月',
    year: '年',
    previousYear: '上一年',
    nextYear: '下一年',
    previousMonth: '上个月',
    nextMonth: '下个月',
    weekdays: ['日', '一', '二', '三', '四', '五', '六'],
    months: [
      '一月', '二月', '三月', '四月', '五月', '六月',
      '七月', '八月', '九月', '十月', '十一月', '十二月'
    ]
  },
  pagination: {
    total: '共 {total} 条',
    page: '页',
    goto: '跳至',
    pageSize: '条/页',
    prev: '上一页',
    next: '下一页'
  },
  upload: {
    dragToUpload: '点击或拖拽文件到此区域上传',
    selectFile: '选择文件',
    uploadSuccess: '上传成功',
    uploadError: '上传失败',
    preview: '预览',
    download: '下载',
    delete: '删除'
  },
  form: {
    required: '此字段为必填项',
    invalid: '格式不正确',
    tooShort: '内容过短',
    tooLong: '内容过长'
  }
}

export default myLocale

扩展现有语言包

typescript
// locale/zh-CN-custom.ts
import zhCN from 'speed-ui-vue/locale/zh-CN'
import type { Locale } from 'speed-ui-vue'

const customZhCN: Locale = {
  ...zhCN,
  // 覆盖特定的文本
  common: {
    ...zhCN.common,
    confirm: '好的',
    cancel: '算了'
  },
  // 添加自定义字段
  custom: {
    welcome: '欢迎使用',
    goodbye: '再见'
  }
}

export default customZhCN

与 Vue I18n 集成

如果你的项目已经使用了 Vue I18n,可以将 Speed UI 的语言包集成进去:

typescript
// i18n/index.ts
import { createI18n } from 'vue-i18n'
import speedUIZhCN from 'speed-ui-vue/locale/zh-CN'
import speedUIEnUS from 'speed-ui-vue/locale/en-US'

const messages = {
  'zh-CN': {
    // 你的应用文本
    app: {
      title: 'Speed UI 示例',
      description: '这是一个示例应用'
    },
    // Speed UI 文本
    speedUI: speedUIZhCN
  },
  'en-US': {
    app: {
      title: 'Speed UI Example',
      description: 'This is an example app'
    },
    speedUI: speedUIEnUS
  }
}

export const i18n = createI18n({
  locale: 'zh-CN',
  messages
})
vue
<template>
  <sp-config-provider :locale="speedUILocale">
    <div>
      <h1>{{ $t('app.title') }}</h1>
      <sp-button>{{ $t('speedUI.common.confirm') }}</sp-button>
    </div>
  </sp-config-provider>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'

const { locale } = useI18n()

const speedUILocale = computed(() => {
  const { $tm } = useI18n()
  return $tm('speedUI')
})
</script>

RTL 支持

Speed UI 支持从右到左(RTL)的语言:

typescript
// 配置 RTL 支持
import { createApp } from 'vue'
import SpeedUI from 'speed-ui-vue'
import arEG from 'speed-ui-vue/locale/ar-EG'

const app = createApp(App)

app.use(SpeedUI, {
  locale: arEG,
  direction: 'rtl' // 启用 RTL 模式
})
css
/* 在 RTL 模式下,组件会自动调整布局 */
[dir="rtl"] .sp-button {
  /* RTL 特定样式 */
}

日期和时间格式化

Speed UI 使用 Intl API 来格式化日期和时间:

typescript
// 自定义日期格式化
import { createApp } from 'vue'
import SpeedUI from 'speed-ui-vue'

const app = createApp(App)

app.use(SpeedUI, {
  locale: {
    ...zhCN,
    dateFormat: {
      dateFormat: 'YYYY-MM-DD',
      timeFormat: 'HH:mm:ss',
      dateTimeFormat: 'YYYY-MM-DD HH:mm:ss'
    }
  }
})

数字格式化

typescript
// 自定义数字格式化
const customLocale = {
  ...zhCN,
  numberFormat: {
    decimal: '.',
    thousands: ',',
    currency: '¥'
  }
}

表单验证消息

Speed UI 集成了 VeeValidate,支持国际化的验证消息:

typescript
import { configure } from 'vee-validate'
import { localize, setLocale } from '@vee-validate/i18n'
import zh_CN from '@vee-validate/i18n/dist/locale/zh_CN.json'
import en from '@vee-validate/i18n/dist/locale/en.json'

configure({
  generateMessage: localize({
    zh_CN,
    en
  })
})

// 设置验证消息语言
setLocale('zh_CN')

最佳实践

  1. 统一管理:将所有语言相关的配置集中管理
  2. 懒加载:对于大型应用,考虑按需加载语言包
  3. 缓存策略:将用户的语言偏好保存到 localStorage
  4. 测试覆盖:确保所有支持的语言都经过测试
  5. 文本长度:考虑不同语言文本长度的差异,预留足够空间

贡献语言包

如果你想为 Speed UI 贡献新的语言包,请参考我们的贡献指南

下一步

Released under the MIT License.