1. 安装依赖

首先,需要安装vue-i18n包:

npm install vue-i18n@9

2. 创建i18n配置文件

2.1 创建i18n主配置文件

在 src/i18n/index.ts 中创建i18n实例:

import { createI18n } from 'vue-i18n'
import zhCN from './locales/zh-CN'
import enUS from './locales/en-US'

// 创建i18n实例
const i18n = createI18n({
  legacy: false, // 使用组合式API
  locale: 'zh-CN', // 默认语言
  fallbackLocale: 'en-US', // 回退语言
  messages: {
    'zh-CN': zhCN,
    'en-US': enUS,
  },
  // 全局使用t函数
  globalInjection: true,
  // 允许组合式API在setup中使用
  allowComposition: true,
})

export default i18n

// 导出类型
export type I18nLanguages = 'zh-CN' | 'en-US'

// 导出语言切换函数
export function setLanguage(lang: I18nLanguages) {
  i18n.global.locale.value = lang
  // 可以在这里添加持久化存储语言设置的逻辑
  localStorage.setItem('language', lang)
}

// 获取当前语言
export function getLanguage(): I18nLanguages {
  return i18n.global.locale.value as I18nLanguages
}

2.2 创建语言包文件

中文语言包 (src/i18n/locales/zh-CN.ts)

// 中文语言包
export default {
  // 公共部分
  common: {
    welcome: '欢迎使用Vue组件库',
    home: '首页',
    button: 'Button 按钮',
    card: 'Card 卡片',
    // 其他公共翻译...
  },
  
  // 按模块组织翻译内容
  home: {
    title: 'Vue组件库',
    subtitle: '一个基于Vue 3和TypeScript的现代组件库',
    // 首页相关翻译...
  },
  
  button: {
    // 按钮组件相关翻译...
  },
  
  card: {
    // 卡片组件相关翻译...
  },
}

英文语言包 (src/i18n/locales/en-US.ts)

// English language pack
export default {
  // Common
  common: {
    welcome: 'Welcome to Vue Component Library',
    home: 'Home',
    button: 'Button',
    card: 'Card',
    // 其他公共翻译...
  },
  
  // 按模块组织翻译内容
  home: {
    title: 'Vue Component Library',
    subtitle: 'A modern component library based on Vue 3 and TypeScript',
    // 首页相关翻译...
  },
  
  button: {
    // 按钮组件相关翻译...
  },
  
  card: {
    // 卡片组件相关翻译...
  },
}

3. 在Vue应用中集成i18n

src/main.ts中引入并使用i18n:

import { createApp } from 'vue'
import App from './App.vue'

// 导入i18n
import i18n from './i18n'

// 创建应用
const app = createApp(App)

// 使用i18n
app.use(i18n)

// 挂载应用
app.mount('#app')

4. 创建语言切换组件

4.1 创建LanguageSwitcher组件

<script setup lang="ts">
import { ref, computed } from 'vue'
import { getLanguage, setLanguage, type I18nLanguages } from '../../i18n'

// 当前语言
const currentLang = ref<I18nLanguages>(getLanguage())

// 下拉菜单状态
const isOpen = ref(false)

// 语言选项
const languages = [
  { value: 'zh-CN', label: '中文' },
  { value: 'en-US', label: 'English' },
]

// 当前语言标签
const currentLangLabel = computed(() => {
  return languages.find(lang => lang.value === currentLang.value)?.label || ''
})

// 切换语言
function changeLang(lang: I18nLanguages) {
  currentLang.value = lang
  setLanguage(lang)
}
</script>

<template>
  <div class="language-switcher">
    <div class="language-switcher__current" @click="isOpen = !isOpen">
      {{ currentLangLabel }}
    </div>
    <div class="language-switcher__dropdown" v-if="isOpen">
      <div 
        v-for="lang in languages" 
        :key="lang.value"
        class="language-switcher__item"
        :class="{ 'is-active': currentLang === lang.value }"
        @click="changeLang(lang.value as I18nLanguages); isOpen = false"
      >
        {{ lang.label }}
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
// 样式部分...
</style>

4.2 导出LanguageSwitcher组件

在 src/components/LanguageSwitcher/index.ts 中:

import LanguageSwitcher from './LanguageSwitcher.vue'

export default LanguageSwitcher

5. 在组件中使用i18n

5.1 在模板中使用

<template>
  <h1>{{ $t('home.title') }}</h1>
  <p>{{ $t('home.subtitle') }}</p>
</template>

5.2 在组合式API中使用

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

const { t } = useI18n()

// 使用t函数获取翻译
const title = t('home.title')
</script>

<template>
  <h1>{{ t('home.title') }}</h1>
  <p>{{ t('home.subtitle') }}</p>
</template>

5.3 动态参数

在语言包中定义带参数的翻译:

export default {
  messages: {
    hello: '你好,{name}!',
  }
}

在组件中使用:

<template>
  <p>{{ $t('messages.hello', { name: 'Vue' }) }}</p>
</template>

6. 最佳实践

### 6.1 组织翻译文件

- 按模块或功能区域组织翻译内容

- 使用嵌套对象保持结构清晰

- 为复杂组件创建专门的翻译命名空间

6.2 处理复数形式

export default {
  items: {
    one: '1个项目',
    other: '{count}个项目'
  }
}

使用:

<template>
  <p>{{ $tc('items', 1) }}</p> <!-- 显示:1个项目 -->
  <p>{{ $tc('items', 10, { count: 10 }) }}</p> <!-- 显示:10个项目 -->
</template>

6.3 日期和数字本地化

<template>
  <p>{{ $d(new Date(), 'long') }}</p> <!-- 日期格式化 -->
  <p>{{ $n(1000, 'currency') }}</p> <!-- 数字格式化 -->
</template>

7. 持久化语言设置

在 setLanguage 函数中,我们已经添加了将语言设置保存到localStorage的逻辑:

export function setLanguage(lang: I18nLanguages) {
  i18n.global.locale.value = lang
  localStorage.setItem('language', lang)
}

可以在应用初始化时读取保存的语言设置:

// 在i18n/index.ts中
const savedLanguage = localStorage.getItem('language') as I18nLanguages
const i18n = createI18n({
  legacy: false,
  locale: savedLanguage || 'zh-CN', // 使用保存的语言或默认语言
  // 其他配置...
})

8. 按需加载语言包

对于大型应用,可以考虑按需加载语言包:

async function loadLanguage(lang: string) {
  const messages = await import(`./locales/${lang}.ts`)
  i18n.global.setLocaleMessage(lang, messages.default)
  setLanguage(lang)
}

总结

通过以上步骤,我们成功地在Vue 3项目中配置了i18n国际化功能。这种配置方式具有以下优点:

  1. 使用组合式API,更符合Vue 3的开发风格

  2. 类型安全,利用TypeScript提供类型检查

  3. 模块化组织翻译内容,便于维护

  4. 提供了语言切换组件,方便用户切换语言

  5. 支持持久化语言设置

通过这种方式,可以轻松地为Vue应用添加多语言支持,提升用户体验