一、当我们需要说"世界语"时
几年前我接手过一个跨境电商项目,老板推门进来就说:"我们的用户下周会覆盖到25个国家"。那一瞬间,我仿佛看到无数个国旗在代码里飘扬。这就是国际化的现实需求——当你的用户遍及全球时,页面上的每个按钮都在说:"你值得拥有母语体验"。
国际化(i18n)不仅仅是文本翻译,它包含了日期格式、货币符号、复数规则等文化差异处理。在Vue生态中,Vue I18n库是我们的瑞士军刀。它支持Vue 2/3版本,截至2023年每周下载量超过200万次,已经成为Vue国际化的事实标准。
二、快速上手:基础配置四部曲
技术栈:Vue 3 + Vue I18n 9.x + Composition API
// main.js
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
const messages = {
en: {
welcome: 'Welcome {name}!',
cart: {
title: 'Your Cart',
items: '{count} item | {count} items'
}
},
ja: {
welcome: 'ようこそ、{name}さん!',
cart: {
title: 'ショッピングカート',
items: '{count} 個の商品'
}
}
}
const i18n = createI18n({
legacy: false, // 启用Composition API模式
locale: 'en',
fallbackLocale: 'en',
messages
})
createApp(App).use(i18n).mount('#app')
这段配置实现了:
- 声明式语言包结构(支持嵌套)
- 插值语法处理动态内容
- 配置回退语言机制
- 启用现代API模式
三、让页面开口说话:模板中的魔法时刻
<template>
<div class="dashboard">
<!-- 基础翻译 -->
<h1>{{ $t('welcome', { name: user.name }) }}</h1>
<!-- 复数处理 -->
<p>{{ $tc('cart.items', itemCount) }}</p>
<!-- 带HTML的翻译 -->
<p v-html="$t('terms')"></p>
</div>
</template>
<script setup>
import { useI18n } from 'vue-i18n'
const { t, tc } = useI18n()
const itemCount = ref(3)
// 代码中的翻译示例
const pageTitle = computed(() => t('cart.title'))
</script>
特别要注意的是:
- 使用
$tc
处理复数规则(英语有单复数,中文没有) v-html
用于渲染带HTML标签的翻译,但要防范XSS攻击- 在组合式API中使用
useI18n
获取翻译函数
四、实时切换:语言选择的仪式感
<template>
<div class="language-switcher">
<button
v-for="lang in availableLocales"
:key="lang"
@click="changeLanguage(lang)"
:class="{ active: locale === lang }"
>
{{ getNativeName(lang) }}
</button>
</div>
</template>
<script setup>
import { useI18n } from 'vue-i18n'
import { loadLocaleMessages } from '@/i18n'
const { locale, availableLocales } = useI18n()
const changeLanguage = async (newLocale) => {
if (!localStorage.getItem(newLocale)) {
const messages = await import(`@/locales/${newLocale}.json`)
loadLocaleMessages(newLocale, messages.default)
}
locale.value = newLocale
document.documentElement.lang = newLocale
}
const getNativeName = (code) => {
return new Intl.DisplayNames([code], { type: 'language' }).of(code)
}
</script>
这里实现了:
- 按钮式语言切换
- 动态加载语言包(重要!)
- 本地缓存优化
- 语义化HTML属性更新
五、性能优化:让你的翻译包学会轻功
当语言包超过300KB时,就需要考虑拆分加载。这是通过Webpack的动态导入实现的:
// i18n.js
export async function loadLocaleMessages(i18n, locale) {
if (!i18n.global.availableLocales.includes(locale)) {
const messages = await import(
/* webpackChunkName: "locale-[request]" */
`@/locales/${locale}.json`
)
i18n.global.setLocaleMessage(locale, messages.default)
}
}
配合路由守卫实现按需加载:
router.beforeEach(async (to) => {
const lang = to.params.lang || 'en'
await loadLocaleMessages(i18n, lang)
i18n.global.locale.value = lang
})
六、高阶技巧:那些你没想到的细节
日期本地化:
<template>
<p>{{ d(new Date(), 'long') }}</p>
</template>
<script setup>
import { useI18n } from 'vue-i18n'
const { d } = useI18n()
</script>
货币格式化:
const price = computed(() => new Intl.NumberFormat(locale.value, {
style: 'currency',
currency: locale.value === 'en' ? 'USD' : 'JPY'
}).format(state.total))
RTL布局支持:
[dir="rtl"] .menu {
direction: rtl;
padding-right: 1rem;
}
七、何时需要国际化?
常见应用场景:
- 跨境电商平台(产品描述、支付流程)
- 企业级后台系统(多地区团队使用)
- 教育类应用(多语言课程内容)
- 新闻门户网站(多语种新闻报道)
- SAAS产品(全球化客户支持)
八、Vue I18n的优缺点对比
优点:
- 深度集成Vue响应式系统
- 完善的复数处理规则
- 支持动态加载语言包
- 活跃的社区支持
- 类型安全(v9支持TypeScript)
缺点:
- 初始配置略显繁琐
- 大规模项目需要自行设计语言包结构
- 实时切换时短暂的白屏问题
- 缺乏内置的翻译管理系统整合
九、踩坑备忘录
- 键名管理:建议采用
path.to.key
的层级结构,建立严格的命名规范 - 翻译质量:专业翻译>机器翻译,特别是法律条款
- 缓存策略:对已加载语言包做本地存储,但要有版本控制
- 回退机制:当某语言翻译不全时,自动切换到备用语言
- 测试策略:使用伪翻译(如所有中文后加※)验证布局
十、从经验中得到的启示
经过多个国际化项目的实践,我总结出"三个统一"原则:
- 管理统一:使用专业的TMS(翻译管理系统)
- 流程统一:开发→翻译→校对→发布的标准化流程
- 样式统一:预留40%的文本扩展空间
十一、总结
国际化不是简单的文本替换,而是建立全球用户的情感连接。通过Vue I18n,我们可以优雅地实现多语言支持,但真正的挑战在于持续维护和用户体验优化。记住,好的国际化就像空气——用户感觉不到它的存在,却不可或缺。