各位靓仔靓女们,晚上好!我是老码农,今天给大家伙唠唠 Vue 项目里如何搞一个靠谱又灵活的国际化(i18n)方案。这玩意儿听起来高大上,其实只要掌握了方法,就能让你写的代码瞬间拥有走向世界的潜力!
咱们今天这堂课,主要围绕以下几个方面展开:
- 选择 i18n 库: 咱们先看看市面上都有哪些好用的库,以及为啥我推荐
vue-i18n
。 - 项目初始化配置: 怎么在 Vue 项目里把
vue-i18n
安排得明明白白。 - 多语言支持: 如何组织和管理你的语言文件,让新增语言变得so easy。
- 动态加载: 别一口气加载所有语言包,按需加载才是王道。
- 日期格式化: 不同国家地区,日期格式千差万别,咱得优雅地处理。
- 组件内使用: 在 Vue 组件里怎么用 i18n,让你的 UI 界面语言切换自如。
- 高级用法: 比如复数形式、参数化等等,让你的 i18n 更强大。
话不多说,咱们这就开始!
1. 选择 i18n 库:vue-i18n
,你的不二之选
市面上 Vue 的 i18n 库不少,但vue-i18n
绝对是主流选择。为啥?
- 文档完善: 遇到问题,找文档是程序员的本能。
vue-i18n
的文档那是相当的全面,各种场景都有示例。 - 社区活跃: 遇到坑,不怕!活跃的社区能帮你快速找到解决方案。
- 功能强大: 支持多语言、动态加载、复数形式、日期格式化等等,你想到的它都有。
- 易于使用: API 简单易懂,上手快。
所以,别犹豫了,vue-i18n
就是你的好伙伴!
2. 项目初始化配置:让 vue-i18n
安家落户
首先,你需要安装 vue-i18n
:
npm install vue-i18n@9
# 或者
yarn add vue-i18n@9
注意这里我们指定了@9
,因为vue-i18n
的v9版本是和vue3兼容的。如果你用的vue2,请安装vue-i18n@8
。
安装完之后,咱们创建一个 i18n.js
文件,用来配置 i18n 实例:
// i18n.js
import { createI18n } from 'vue-i18n'
function loadLocaleMessages() {
const locales = require.context('./locales', true, /[A-Za-z0-9-_,s]+.json$/i)
const messages = {}
locales.keys().forEach(key => {
const matched = key.match(/([A-Za-z0-9-_]+)./i)
if (matched && matched.length > 1) {
const locale = matched[1]
messages[locale] = locales(key).default
}
})
return messages
}
const i18n = createI18n({
locale: process.env.VUE_APP_I18N_LOCALE || 'zh-CN',
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en-US',
messages: loadLocaleMessages()
})
export default i18n
这段代码做了以下几件事:
- 引入
createI18n
: 这是 Vue 3 提供的创建 i18n 实例的方法。 loadLocaleMessages
函数: 这个函数负责加载locales
目录下的所有语言文件。它使用require.context
来动态导入locales
目录下的所有.json
文件,并将它们合并成一个messages
对象。- 创建 i18n 实例: 使用
createI18n
创建 i18n 实例,并配置locale
(当前语言)、fallbackLocale
(备用语言)和messages
(语言包)。 - 导出 i18n 实例: 方便在其他地方使用。
接下来,在你的 main.js
文件中,引入并使用 i18n 实例:
// 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')
这样,vue-i18n
就成功地集成到你的 Vue 项目里了!
3. 多语言支持:构建你的语言帝国
接下来,咱们得创建语言文件。按照上面的配置,我们需要在项目根目录下创建一个 locales
目录,并在里面创建不同的语言文件,例如 zh-CN.json
、en-US.json
、ja-JP.json
等等。
/src
/locales
/zh-CN.json
/en-US.json
/ja-JP.json
/components
/App.vue
/main.js
/i18n.js
每个语言文件都是一个 JSON 对象,包含了该语言对应的所有文本信息。例如:
zh-CN.json:
{
"message": {
"hello": "你好,世界!",
"welcome": "欢迎来到我的网站!",
"productName": "产品名称"
},
"date": {
"formats": {
"short": {
"year": "numeric",
"month": "short",
"day": "numeric"
},
"long": {
"year": "numeric",
"month": "long",
"day": "numeric",
"weekday": "long"
}
}
}
}
en-US.json:
{
"message": {
"hello": "Hello, world!",
"welcome": "Welcome to my website!",
"productName": "Product Name"
},
"date": {
"formats": {
"short": {
"year": "numeric",
"month": "short",
"day": "numeric"
},
"long": {
"year": "numeric",
"month": "long",
"day": "numeric",
"weekday": "long"
}
}
}
}
ja-JP.json:
{
"message": {
"hello": "こんにちは、世界!",
"welcome": "私のウェブサイトへようこそ!",
"productName": "製品名"
},
"date": {
"formats": {
"short": {
"year": "numeric",
"month": "short",
"day": "numeric"
},
"long": {
"year": "numeric",
"month": "long",
"day": "numeric",
"weekday": "long"
}
}
}
}
注意:JSON 文件的格式一定要正确,否则会加载失败。
4. 动态加载:按需加载,告别臃肿
如果你的应用支持的语言很多,一次性加载所有语言包会影响性能。这时候,动态加载就派上用场了。
修改 i18n.js
文件,添加一个 loadLocaleMessagesAsync
函数:
// i18n.js
import { createI18n } from 'vue-i18n'
function loadLocaleMessages() {
const locales = require.context('./locales', true, /[A-Za-z0-9-_,s]+.json$/i)
const messages = {}
locales.keys().forEach(key => {
const matched = key.match(/([A-Za-z0-9-_]+)./i)
if (matched && matched.length > 1) {
const locale = matched[1]
messages[locale] = locales(key).default
}
})
return messages
}
const i18n = createI18n({
locale: process.env.VUE_APP_I18N_LOCALE || 'zh-CN',
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en-US',
messages: loadLocaleMessages()
})
export async function loadLocaleMessagesAsync(locale) {
// 如果已经加载过了,就不再加载
if (i18n.global.availableLocales.includes(locale)) {
return Promise.resolve()
}
try {
const messages = await import(
/* webpackChunkName: "locale-[request]" */ `./locales/${locale}.json`
)
i18n.global.setLocaleMessage(locale, messages.default)
i18n.global.locale.value = locale
return Promise.resolve()
} catch (e) {
console.error(e)
return Promise.reject(e)
}
}
export default i18n
这个 loadLocaleMessagesAsync
函数会异步加载指定的语言文件,并将其添加到 i18n 实例中。
在你的组件中,你可以这样使用它:
// MyComponent.vue
<template>
<div>
<button @click="changeLocale('en-US')">English</button>
<button @click="changeLocale('ja-JP')">Japanese</button>
<p>{{ $t('message.hello') }}</p>
</div>
</template>
<script>
import { loadLocaleMessagesAsync } from '../i18n'
export default {
methods: {
async changeLocale(locale) {
try {
await loadLocaleMessagesAsync(locale)
} catch (e) {
console.error(e)
}
}
}
}
</script>
这样,只有当你点击按钮切换到对应的语言时,才会加载该语言的语言包。
5. 日期格式化:让日期更懂你
不同国家地区的日期格式千差万别,vue-i18n
提供了强大的日期格式化功能。
在你的语言文件中,定义不同的日期格式:
zh-CN.json:
{
"message": {
"hello": "你好,世界!",
"welcome": "欢迎来到我的网站!",
"productName": "产品名称"
},
"date": {
"formats": {
"short": {
"year": "numeric",
"month": "short",
"day": "numeric"
},
"long": {
"year": "numeric",
"month": "long",
"day": "numeric",
"weekday": "long"
}
}
}
}
en-US.json:
{
"message": {
"hello": "Hello, world!",
"welcome": "Welcome to my website!",
"productName": "Product Name"
},
"date": {
"formats": {
"short": {
"year": "numeric",
"month": "short",
"day": "numeric"
},
"long": {
"year": "numeric",
"month": "long",
"day": "numeric",
"weekday": "long"
}
}
}
}
然后在你的组件中,使用 $d
来格式化日期:
// MyComponent.vue
<template>
<div>
<p>Short Date: {{ $d(date, 'short') }}</p>
<p>Long Date: {{ $d(date, 'long') }}</p>
</div>
</template>
<script>
export default {
data() {
return {
date: new Date()
}
}
}
</script>
$d
函数接收两个参数:
- date: 要格式化的日期对象。
- format: 日期格式的名称,对应于语言文件中定义的
date.formats
对象中的键。
6. 组件内使用:让 UI 界面语言切换自如
在 Vue 组件中使用 i18n 非常简单,只需要使用 $t
函数即可。
// MyComponent.vue
<template>
<div>
<h1>{{ $t('message.welcome') }}</h1>
<p>{{ $t('message.hello') }}</p>
</div>
</template>
$t
函数接收一个参数:
- key: 语言文件中对应的键。
如果你的语言文件是嵌套的,可以使用点号来访问深层级的键。例如,message.hello
。
7. 高级用法:让你的 i18n 更强大
vue-i18n
还提供了很多高级用法,例如:
- 复数形式: 根据数量显示不同的文本。
- 参数化: 在文本中使用变量。
- 自定义格式: 定义自己的日期、数字格式。
咱们一个一个来看。
复数形式:
在你的语言文件中,使用 plural
属性来定义复数形式:
en-US.json:
{
"message": {
"apples": "I have {count} apple | I have {count} apples"
}
}
然后在你的组件中,使用 $t
函数的 choice
选项来选择正确的复数形式:
// MyComponent.vue
<template>
<div>
<p>{{ $t('message.apples', { count: appleCount }, appleCount) }}</p>
</div>
</template>
<script>
export default {
data() {
return {
appleCount: 1
}
}
}
</script>
$t
函数的第三个参数 appleCount
会传递给 choice
选项,vue-i18n
会根据 appleCount
的值来选择正确的复数形式。
参数化:
在你的语言文件中,使用花括号 {}
来定义变量:
en-US.json:
{
"message": {
"greeting": "Hello, {name}!"
}
}
然后在你的组件中,使用 $t
函数的第二个参数来传递变量:
// MyComponent.vue
<template>
<div>
<p>{{ $t('message.greeting', { name: 'John' }) }}</p>
</div>
</template>
自定义格式:
vue-i18n
允许你定义自己的日期、数字格式。具体方法可以参考 vue-i18n
的官方文档。
总结
今天咱们一起学习了如何在 Vue 项目中设计一个可扩展的国际化解决方案。从选择 i18n 库、项目初始化配置、多语言支持、动态加载、日期格式化、组件内使用,到高级用法,都做了详细的讲解。
希望大家能够掌握这些知识,让你的 Vue 项目拥有走向世界的潜力!
速查表:常用 API
API | 描述 | 示例 |
---|---|---|
$t(key) |
获取指定 key 对应的翻译文本 | $t('message.hello') |
$d(date, format) |
格式化日期 | $d(new Date(), 'short') |
$n(number, format) |
格式化数字(需要安装 @intlify/vue-i18n 的 NumberFormat 相关功能) |
$n(1234567.89, 'currency') 需要先定义 currency 格式在语言文件中。 |
i18n.global.locale.value |
获取或设置当前语言 | i18n.global.locale.value = 'en-US' |
loadLocaleMessagesAsync(locale) |
异步加载指定语言包 | loadLocaleMessagesAsync('ja-JP') |
记住,实践才是检验真理的唯一标准。多写代码,多踩坑,才能真正掌握这些知识。 祝大家编码愉快!