简介
在Vue 3项目中实现国际化时,我们需要使用vue-i18n的版本9或更高版本,这个版本专门适配了Vue 3的Composition API。本文将详细介绍如何在Vue 3项目中实现国际化,以及相关的最佳实践。
安装与基础配置
首先需要安装适配Vue 3的vue-i18n:
bash
npm install vue-i18n@9
在Vue 3项目中进行基础配置:
typescript
// i18n/index.ts
import { createI18n } from 'vue-i18n'
// 准备语言包
const messages = {
zh: {
message: {
hello: '你好,世界',
welcome: '欢迎来到 {name}'
}
},
en: {
message: {
hello: 'Hello world',
welcome: 'Welcome to {name}'
}
}
}
// 创建i18n实例
export const i18n = createI18n({
legacy: false, // 使用Composition API模式
locale: 'zh',
fallbackLocale: 'en',
messages
})
// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import { i18n } from './i18n'
const app = createApp(App)
app.use(i18n)
app.mount('#app')
使用方法
1. 在模板中使用(Composition API)
vue
<template>
<div>
<p>{{ t('message.hello') }}</p>
<p>{{ t('message.welcome', { name: 'Vue 3' }) }}</p>
</div>
</template>
<script setup>
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
</script>
2. 在JavaScript/TypeScript中使用
typescript
import { useI18n } from 'vue-i18n'
// 在setup内使用
const MyComponent = defineComponent({
setup() {
const { t, locale } = useI18n()
const sayHello = () => {
console.log(t('message.hello'))
}
return {
sayHello
}
}
})
3. 动态切换语言
typescript
import { useI18n } from 'vue-i18n'
const LanguageSwitcher = defineComponent({
setup() {
const { locale } = useI18n()
const changeLanguage = (lang: string) => {
locale.value = lang
}
return {
changeLanguage
}
}
})
进阶特性
1. 数字本地化
typescript
const { n } = useI18n()
// 在模板中
<template>
<p>{{ n(100, 'currency') }}</p>
</template>
// 在setup中
setup() {
const { n } = useI18n()
const price = n(100, 'currency')
return { price }
}
2. 日期时间本地化
typescript
import { createI18n } from 'vue-i18n'
const i18n = createI18n({
legacy: false,
datetimeFormats: {
'zh': {
short: {
year: 'numeric',
month: 'short',
day: 'numeric'
}
},
'en': {
short: {
year: 'numeric',
month: 'short',
day: 'numeric'
}
}
}
})
// 在组件中使用
const { d } = useI18n()
const formattedDate = d(new Date(), 'short')
类型支持
Vue 3的i18n提供了更好的TypeScript支持:
typescript
// types/i18n.d.ts
import { DefineLocaleMessage } from 'vue-i18n'
declare module 'vue-i18n' {
export interface DefineLocaleMessage {
message: {
hello: string
welcome: string
}
}
}
最佳实践
1. 使用模块化的语言包
typescript
// locales/zh.ts
export default {
message: {
hello: '你好'
}
} as const
// locales/index.ts
import zh from './zh'
import en from './en'
export default {
zh,
en
} as const
2. 异步加载语言包
typescript
// i18n.ts
import { createI18n } from 'vue-i18n'
const i18n = createI18n({
legacy: false,
locale: 'zh',
fallbackLocale: 'en',
messages: {}
})
export async function loadLanguageAsync(locale: string) {
const messages = await import(`./locales/${locale}.ts`)
i18n.global.setLocaleMessage(locale, messages.default)
i18n.global.locale.value = locale
return messages
}
3. 结合Vue Router使用
typescript
import { createRouter } from 'vue-router'
import { i18n } from './i18n'
const router = createRouter({
// router 配置
})
router.beforeEach(async (to, from, next) => {
const paramsLocale = to.params.locale as string
// 加载对应的语言包
if (paramsLocale) {
await loadLanguageAsync(paramsLocale)
}
return next()
})
Vue 3特有的注意事项
-
Composition API的使用:
- 必须在setup()内使用useI18n()
- 注意作用域问题,全局配置使用i18n.global
-
与响应式系统的集成:
typescript
import { watch } from 'vue'
import { useI18n } from 'vue-i18n'
export function useLanguageWatcher() {
const { locale } = useI18n()
watch(locale, (newLocale) => {
document.querySelector('html')?.setAttribute('lang', newLocale)
})
}
- 性能优化:
typescript
// 避免不必要的重渲染
const { t } = useI18n({
useScope: 'local' // 使用本地作用域
})
总结
Vue 3的i18n实现相比Vue 2有以下主要改进:
- 更好的TypeScript支持
- 完整的Composition API支持
- 更灵活的作用域控制
- 更好的性能优化选项
- 更现代的模块化支持
在使用Vue 3的i18n时,需要特别注意:
- 使用Composition API的正确方式
- TypeScript类型定义的支持
- 全局状态和组件级别状态的区分
- 异步加载的性能优化