各位观众老爷们,大家好!今天咱们来聊聊 Vue 项目里的国际化(i18n)这个磨人的小妖精。别怕,今天咱们就把这妖精给收了,让你的项目也能说一口流利的“各国语言”。
国际化:不只是翻译
首先,咱们得明白,国际化不仅仅是把文字翻译成不同的语言。它涉及到日期、时间、货币格式等等,甚至包括从右到左的阅读习惯。不过,在前端,我们通常关注的是文本内容的翻译和一些简单的格式化。
Vue + i18n:天生一对
Vue 和 i18n 简直是天生一对!有很多 i18n 库可以和 Vue 完美结合,咱们今天就用 vue-i18n 这个官方推荐的库来做演示。
安装 vue-i18n
首先,打开你的终端,输入:
npm install vue-i18n@9
# 或者
yarn add vue-i18n@9
注意,这里指定了版本号 @9
。因为vue-i18n 版本 9 是兼容vue3 的.
初始化 i18n 实例
接下来,我们需要创建一个 i18n 实例。在你的 src
目录下,创建一个 i18n
文件夹,然后在里面创建一个 index.js
文件:
// src/i18n/index.js
import { createI18n } from 'vue-i18n'
const i18n = createI18n({
locale: 'zh-CN', // 默认语言
fallbackLocale: 'en-US', // 备用语言,当没有对应翻译时使用
messages: {
'zh-CN': {
message: {
hello: '你好,世界!',
welcome: '欢迎来到我的网站!',
dynamic: '这是一个动态文本:{value}'
}
},
'en-US': {
message: {
hello: 'Hello, world!',
welcome: 'Welcome to my website!',
dynamic: 'This is a dynamic text: {value}'
}
}
}
})
export default i18n
这段代码做了什么?
- 导入
createI18n
: 这是 Vue I18n 的核心函数,用于创建 i18n 实例。 - 创建 i18n 实例: 使用
createI18n
创建一个 i18n 实例,并配置以下选项:locale
: 设置默认语言为zh-CN
(简体中文)。fallbackLocale
: 设置备用语言为en-US
(美国英语)。如果当前语言没有对应的翻译,则使用备用语言。messages
: 定义不同语言的翻译文本。这里定义了zh-CN
和en-US
两种语言的翻译,每个语言都包含一个message
对象,其中包含一些键值对,键是翻译的标识符,值是翻译后的文本。 动态文本示例dynamic
使用了占位符{value}
,稍后我们会看到如何替换它。
- 导出 i18n 实例: 将创建的 i18n 实例导出,以便在 Vue 应用中使用。
在 Vue 应用中使用 i18n
在你的 main.js
文件中,导入 i18n 实例并将其安装到 Vue 应用中:
// src/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 组件中使用 $t
方法来获取翻译后的文本了。 $t
是 vue-i18n 提供的全局方法,用于翻译文本。
// src/App.vue
<template>
<div>
<h1>{{ $t('message.hello') }}</h1>
<p>{{ $t('message.welcome') }}</p>
<p>{{ $t('message.dynamic', { value: 'Vue.js' }) }}</p>
<button @click="changeLocale('en-US')">切换到英文</button>
<button @click="changeLocale('zh-CN')">切换到中文</button>
</div>
</template>
<script>
import { useI18n } from 'vue-i18n'
export default {
setup() {
const { t, locale } = useI18n()
const changeLocale = (newLocale) => {
locale.value = newLocale
}
return {
t,
changeLocale
}
}
}
</script>
这段代码做了什么?
- 引入
useI18n
: 这是一个 Vue I18n 提供的 hook,用于在 setup 函数中使用 i18n 功能。 - 使用
useI18n
: 调用useI18n
hook,获取t
(翻译函数) 和locale
(当前语言) 对象。 - 使用
$t
在模板中翻译: 在模板中使用$t('message.hello')
获取message.hello
对应的翻译文本。 - 动态文本: 使用
$t('message.dynamic', { value: 'Vue.js' })
获取message.dynamic
对应的翻译文本,并使用{ value: 'Vue.js' }
替换文本中的占位符{value}
。 - 切换语言: 创建一个
changeLocale
方法,用于切换语言。该方法将locale.value
设置为新的语言代码。 - 返回
t
和changeLocale
: 将t
和changeLocale
方法返回,以便在模板中使用。
现在运行你的 Vue 项目,你应该能看到页面上的文本被翻译成中文或英文。点击按钮可以切换语言。
动态加载语言文件
上面的例子把所有的翻译都写在了一个文件里。如果你的项目很大,这显然不是一个好主意。更好的做法是把不同语言的翻译放在不同的文件中,然后动态加载它们。
首先,在 i18n
目录下创建 locales
文件夹,然后在里面创建 zh-CN.json
和 en-US.json
文件:
// src/i18n/locales/zh-CN.json
{
"message": {
"hello": "你好,世界!",
"welcome": "欢迎来到我的网站!",
"dynamic": "这是一个动态文本:{value}"
}
}
// src/i18n/locales/en-US.json
{
"message": {
"hello": "Hello, world!",
"welcome": "Welcome to my website!",
"dynamic": "This is a dynamic text: {value}"
}
}
然后,修改 i18n/index.js
文件,使用 createI18n
的 messages
选项,但不再直接定义翻译文本,而是定义一个函数来加载翻译文件:
// src/i18n/index.js
import { createI18n } from 'vue-i18n'
async function loadLocaleMessages(locale) {
const messages = await import(`./locales/${locale}.json`)
return messages.default
}
const i18n = createI18n({
locale: 'zh-CN',
fallbackLocale: 'en-US',
messages: {} // 初始化为空对象,后续动态加载
})
export async function setI18nLanguage(locale) {
i18n.global.locale.value = locale // 直接修改 i18n 实例的 locale
// 如果已经加载过该语言,则直接返回
if (i18n.global.availableLocales.includes(locale)) {
return
}
// 加载语言文件
const messages = await loadLocaleMessages(locale)
// 将加载的语言文件添加到 i18n 实例中
i18n.global.setLocaleMessage(locale, messages)
i18n.global.availableLocales.push(locale) // 记录已加载的语言
}
export default i18n
这段代码做了什么?
loadLocaleMessages
函数: 这是一个异步函数,用于动态加载语言文件。它使用import()
函数加载指定语言的 JSON 文件,并返回其默认导出 (也就是 JSON 对象)。setI18nLanguage
函数: 这是一个异步函数,用于设置 i18n 的语言。它接收一个语言代码作为参数。- 首先,它设置 i18n 实例的
locale
属性为新的语言代码。 - 然后,它检查是否已经加载过该语言。如果已经加载过,则直接返回。
- 如果还没有加载过该语言,则调用
loadLocaleMessages
函数加载语言文件。 - 最后,它使用
i18n.global.setLocaleMessage
函数将加载的语言文件添加到 i18n 实例中,并使用i18n.global.availableLocales.push(locale)
记录已加载的语言。
- 首先,它设置 i18n 实例的
- i18n 实例初始化: 使用
createI18n
创建一个 i18n 实例,并将messages
选项初始化为空对象。这是因为我们将在运行时动态加载语言文件。
现在,我们需要修改 App.vue
组件,使用 setI18nLanguage
函数来切换语言:
// src/App.vue
<template>
<div>
<h1>{{ $t('message.hello') }}</h1>
<p>{{ $t('message.welcome') }}</p>
<p>{{ $t('message.dynamic', { value: 'Vue.js' }) }}</p>
<button @click="changeLocale('en-US')">切换到英文</button>
<button @click="changeLocale('zh-CN')">切换到中文</button>
</div>
</template>
<script>
import { useI18n } from 'vue-i18n'
import { setI18nLanguage } from './i18n'
export default {
setup() {
const { t, locale } = useI18n()
const changeLocale = async (newLocale) => {
await setI18nLanguage(newLocale)
locale.value = newLocale // 确保 locale 同步更新
}
return {
t,
changeLocale
}
}
}
</script>
这段代码修改了 changeLocale
函数,使其调用 setI18nLanguage
函数来加载和设置语言。 setI18nLanguage
是一个异步操作,所以我们在 changeLocale
中使用了 await
关键字,以确保语言文件加载完成后再更新 locale.value
。
更好的体验:自动根据浏览器语言设置默认语言
为了提供更好的用户体验,我们可以根据用户的浏览器语言自动设置默认语言。
在 i18n/index.js
中,添加一个函数来获取浏览器语言:
// src/i18n/index.js
function getBrowserLocale() {
const navigatorLocale = navigator.language || navigator.userLanguage
const lang = navigatorLocale.substr(0, 2) // 获取语言的前两个字母
// 根据实际情况返回支持的语言代码
if (lang === 'zh') {
return 'zh-CN'
} else if (lang === 'en') {
return 'en-US'
} else {
return 'en-US' // 默认使用英语
}
}
// ... 其他代码 ...
const i18n = createI18n({
locale: getBrowserLocale(), // 根据浏览器语言设置默认语言
fallbackLocale: 'en-US',
messages: {}
})
这段代码做了什么?
getBrowserLocale
函数: 这是一个函数,用于获取浏览器的语言。- 它首先尝试获取
navigator.language
或navigator.userLanguage
属性,这些属性包含了浏览器的语言信息。 - 然后,它使用
substr(0, 2)
获取语言代码的前两个字母。 - 最后,它根据语言代码返回支持的语言代码。如果不支持该语言,则返回默认语言
en-US
。
- 它首先尝试获取
- i18n 实例初始化: 在创建 i18n 实例时,将
locale
选项设置为getBrowserLocale()
函数的返回值。
更进一步:使用 i18n 组件
vue-i18n 还提供了一些组件,可以更方便地在模板中使用翻译。
<i18n>
组件: 可以格式化数字、日期和时间。<i18n-t>
组件: 用于翻译文本,功能和$t
方法类似。
例如,我们可以使用 <i18n-t>
组件来翻译 App.vue
中的文本:
// src/App.vue
<template>
<div>
<h1><i18n-t keypath="message.hello" /></h1>
<p><i18n-t keypath="message.welcome" /></p>
<p><i18n-t keypath="message.dynamic" :values="{ value: 'Vue.js' }" /></p>
<button @click="changeLocale('en-US')">切换到英文</button>
<button @click="changeLocale('zh-CN')">切换到中文</button>
</div>
</template>
这段代码使用了 <i18n-t>
组件来翻译文本。 keypath
属性指定了翻译的标识符, :values
属性指定了动态文本的占位符替换值。
i18n 的高级用法:复数形式、日期格式化等等
vue-i18n
还支持很多高级用法,例如:
- 复数形式: 根据数量选择不同的翻译文本。
- 日期格式化: 根据语言习惯格式化日期和时间。
- 货币格式化: 根据语言习惯格式化货币。
这些高级用法可以参考 vue-i18n
的官方文档。
总结
今天我们学习了如何在 Vue 项目中使用 vue-i18n
实现国际化。我们从最简单的文本翻译开始,然后学习了如何动态加载语言文件,以及如何根据浏览器语言设置默认语言。最后,我们还介绍了 vue-i18n
提供的一些组件和高级用法。
希望今天的讲座能帮助你更好地理解和使用 vue-i18n
。 记住,国际化不仅仅是翻译,更是一种对用户的尊重。 好了,今天的讲座就到这里,下次再见!
表格总结:
功能 | 实现方式 | 代码示例 |
---|---|---|
安装 vue-i18n | npm install vue-i18n@9 或 yarn add vue-i18n@9 |
(终端命令) |
初始化 i18n | 使用 createI18n 创建 i18n 实例,配置 locale , fallbackLocale , messages 。 |
javascript import { createI18n } from 'vue-i18n' const i18n = createI18n({ locale: 'zh-CN', fallbackLocale: 'en-US', messages: { ... } }) export default i18n |
应用 i18n | 在 main.js 中 app.use(i18n) 。 |
javascript import { createApp } from 'vue' import App from './App.vue' import i18n from './i18n' const app = createApp(App) app.use(i18n) app.mount('#app') |
使用翻译 | 使用 $t 方法或 <i18n-t> 组件。 |
vue <template> <p>{{ $t('message.hello') }}</p> <i18n-t keypath="message.welcome" /> </template> |
动态加载语言文件 | 创建 loadLocaleMessages 函数加载 JSON 文件,使用 setI18nLanguage 函数设置语言和加载语言文件。 |
javascript async function loadLocaleMessages(locale) { ... } export async function setI18nLanguage(locale) { ... } |
自动检测浏览器语言 | 使用 getBrowserLocale 函数获取浏览器语言,作为 locale 的默认值。 |
javascript function getBrowserLocale() { ... } const i18n = createI18n({ locale: getBrowserLocale(), ... }) |
i18n 组件 | <i18n> (格式化数字、日期、时间), <i18n-t> (翻译文本)。 |
vue <template> <i18n tag="div" :path="'number'" :locale="currentLocale" :number="1234567.89" format="currency"/> <i18n-t keypath="message.dynamic" :values="{ value: 'Vue.js' }" /> </template> |
希望这个表格能够帮助你更好地理解 Vue i18n 的使用方法。 记住,多实践才能真正掌握!