1.i18n的基础介绍
i18n(Internationalization的缩写,18代表首尾字母之间的字母数)是"国际化"的简称。它的主要目的是让应用程序能够适应不同的语言和地区的需求。为什么需要i18n?全球化需求,应用需要服务不同国家的用户,满足多语言市场的业务拓展需求,提升产品的国际竞争力。i18n不仅仅是一个翻译工具,而是一个完整的国际化解决方案,它能够帮助我们更好地开发和维护国际化应用,提升用户体验和开发效率。在现代web开发中,i18n已经成为构建全球化应用的必要工具。
2.安装配置
# 1. 安装 vue-i18n
npm install vue-i18n@next # Vue 3.x
# 或
npm install vue-i18n@8 # Vue 2.x
3.基础配置
// i18n/index.js
import { createI18n } from 'vue-i18n'
// 语言包配置
const messages = {
// 中文语言包
zh: {
message: {
hello: '你好',
welcome: '欢迎来到{name}',
// 导航
nav: {
home: '首页',
about: '关于我们',
user: '用户中心'
},
// 表单
form: {
username: '用户名',
password: '密码',
submit: '提交',
reset: '重置'
}
}
},
// 英文语言包
en: {
message: {
hello: 'Hello',
welcome: 'Welcome to {name}',
nav: {
home: 'Home',
about: 'About',
user: 'User Center'
},
form: {
username: 'Username',
password: 'Password',
submit: 'Submit',
reset: 'Reset'
}
}
}
}
// 创建 i18n 实例
const i18n = createI18n({
locale: 'zh', // 设置默认语言
fallbackLocale: 'en', // 设置备用语言
messages, // 语言包
legacy: false, // 使用组合式API
globalInjection: true // 全局注入 $t 函数
})
export default i18n
4.在 main.js 中注册
import { createApp } from 'vue'
import App from './App.vue'
import i18n from './i18n'
const app = createApp(App)
app.use(i18n)
app.mount('#app')
5.基础用法
<!-- 1. 模板中使用 -->
<template>
<!-- 基本翻译 -->
<h1>{{ $t('message.hello') }}</h1>
<!-- 带参数翻译 -->
<p>{{ $t('message.welcome', { name: 'Vue' }) }}</p>
<!-- 切换语言 -->
<select v-model="$i18n.locale">
<option value="zh">中文</option>
<option value="en">English</option>
</select>
</template>
<!-- 2. 组合式API中使用 -->
<script setup>
import { useI18n } from 'vue-i18n'
const { t, locale } = useI18n()
// 使用翻译
console.log(t('message.hello'))
// 切换语言
const changeLanguage = (lang) => {
locale.value = lang
}
</script>
6.进阶用法
// 1. 数字格式化
const i18n = createI18n({
numberFormats: {
zh: {
currency: {
style: 'currency',
currency: 'CNY'
}
},
en: {
currency: {
style: 'currency',
currency: 'USD'
}
}
}
})
// 使用
<template>
<p>{{ $n(100, 'currency') }}</p>
</template>
// 2. 日期格式化
const i18n = createI18n({
datetimeFormats: {
zh: {
short: {
year: 'numeric',
month: 'short',
day: 'numeric'
}
},
en: {
short: {
year: 'numeric',
month: 'short',
day: 'numeric'
}
}
}
})
// 使用
<template>
<p>{{ $d(new Date(), 'short') }}</p>
</template>
7.动态加载语言包
// i18n/loader.js
export const loadLanguageAsync = async (lang) => {
// 动态导入语言文件
const messages = await import(`./locales/${lang}.js`)
// 设置语言包
i18n.global.setLocaleMessage(lang, messages.default)
// 切换语言
i18n.global.locale.value = lang
// 存储语言选择
localStorage.setItem('language', lang)
return messages.default
}
// 使用
const changeLanguage = async (lang) => {
await loadLanguageAsync(lang)
}
8.语言包管理
// locales/zh.js
export default {
message: {
// 通用
common: {
confirm: '确认',
cancel: '取消',
save: '保存'
},
// 错误信息
error: {
network: '网络错误',
timeout: '请求超时',
notFound: '资源不存在'
},
// 业务模块
user: {
login: '登录',
register: '注册',
profile: '个人资料'
}
}
}
9.持久化语言选择
// i18n/persistence.js
export const setupI18nPersistence = (i18n) => {
// 从本地存储获取语言设置
const savedLanguage = localStorage.getItem('language')
if (savedLanguage) {
i18n.global.locale.value = savedLanguage
} else {
// 获取浏览器语言
const browserLang = navigator.language.split('-')[0]
i18n.global.locale.value = browserLang
localStorage.setItem('language', browserLang)
}
}
10.最佳实践
// 1. 创建语言切换组件
const LanguageSwitcher = {
setup() {
const { locale, t } = useI18n()
const languages = [
{ code: 'zh', name: '中文' },
{ code: 'en', name: 'English' }
]
const changeLanguage = async (lang) => {
await loadLanguageAsync(lang)
document.querySelector('html').setAttribute('lang', lang)
}
return { locale, languages, changeLanguage }
}
}
// 2. 路由标题国际化
router.beforeEach((to, from, next) => {
const { t } = i18n.global
document.title = t(to.meta.title) || '默认标题'
next()
})
// 3. 错误信息国际化
const handleError = (error) => {
const { t } = i18n.global
showMessage(t(`error.${error.code}`))
}
11.使用建议:
- 合理组织语言包结构
- 使用命名空间避免冲突
- 实现语言选择持久化
- 考虑动态加载优化性能
- 注意日期和数字的本地化
- 做好错误信息的国际化
- 保持语言包的同步更新