各位靓仔靓女,晚上好!我是你们的老朋友(虽然可能有些人是第一次见我),今天咱们就来聊聊 Vue 应用里的国际化(i18n)这个事儿。
说实话,国际化这玩意儿,听起来高大上,其实就是让你的网站或者应用能说各国语言,让来自五湖四海的朋友都能宾至如归。但是,别以为简单地把文字翻译一下就完事了,它涉及到很多细节,比如日期、货币、数字的格式,还有不同语言的阅读习惯等等。
今天,咱们的目标是设计一个可扩展、支持多语言、动态加载和日期格式化的 Vue i18n 解决方案。保证你听完之后,也能轻松搞定国际化,让你的应用走向世界!
第一部分:基础架构设计
首先,我们需要选择一个靠谱的 i18n 库。Vue 社区里比较流行的有 vue-i18n
和 vuex-i18n
。vue-i18n
是官方推荐的,功能强大,文档齐全。vuex-i18n
则更适合大型应用,因为它把语言数据存储在 Vuex 中,方便管理。
咱们今天就以 vue-i18n
为例,搭建一个基础的架构。
-
安装 vue-i18n:
npm install vue-i18n@9
注意,我这里指定了版本@9,因为vue-i18n 8 对应vue2,vue-i18n 9对应vue3。
-
创建 i18n 实例:
在你的项目里创建一个
i18n.js
文件(或者你喜欢的名字),用来初始化vue-i18n
。// i18n.js import { createI18n } from 'vue-i18n' const i18n = createI18n({ legacy: false, // 如果使用Composition API,需要设置为false locale: 'zh-CN', // 默认语言 fallbackLocale: 'en-US', // 备用语言 messages: { 'zh-CN': { message: { hello: '你好,世界!', welcome: '欢迎来到我的网站!' } }, 'en-US': { message: { hello: 'Hello, world!', welcome: 'Welcome to my website!' } } } }) export default i18n
解释一下:
legacy: false
:这个是为了兼容 Vue 3 的 Composition API,必须设置为false
。locale: 'zh-CN'
:设置默认语言为简体中文。fallbackLocale: 'en-US'
:设置备用语言为美式英语。如果当前语言没有对应的翻译,就会显示备用语言的翻译。messages
:存放不同语言的翻译数据。这里我们简单地定义了中文和英文的hello
和welcome
消息。
-
在 Vue 应用中使用 i18n:
在
main.js
中引入 i18n 实例,并将其挂载到 Vue 应用上。// 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')
-
在组件中使用翻译:
现在,你就可以在组件中使用
$t
方法来获取翻译了。<template> <div> <h1>{{ $t('message.hello') }}</h1> <p>{{ $t('message.welcome') }}</p> </div> </template> <script> export default { name: 'HelloWorld' } </script>
运行你的应用,你应该能看到 "你好,世界!" 和 "欢迎来到我的网站!" 了。
第二部分:动态加载语言包
上面的例子里,所有的语言数据都放在 i18n.js
文件里。如果你的应用支持的语言很多,或者语言数据量很大,这样做就不太合适了。更好的做法是动态加载语言包,按需加载。
-
创建语言包文件:
在你的项目里创建一个
locales
文件夹,用来存放不同语言的语言包文件。例如:locales/ ├── en-US.json └── zh-CN.json
en-US.json
:{ "message": { "hello": "Hello, world!", "welcome": "Welcome to my website!" } }
zh-CN.json
:{ "message": { "hello": "你好,世界!", "welcome": "欢迎来到我的网站!" } }
-
修改 i18n.js 文件:
// 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({ legacy: false, locale: process.env.VUE_APP_I18N_LOCALE || 'zh-CN', fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en-US', messages: loadLocaleMessages() }) export default i18n
解释一下:
loadLocaleMessages()
函数:这个函数使用require.context
来动态加载locales
文件夹下的所有.json
文件,并将它们合并成一个messages
对象。process.env.VUE_APP_I18N_LOCALE
和process.env.VUE_APP_I18N_FALLBACK_LOCALE
: 从环境变量中读取当前语言和备用语言。 需要在.env文件中进行配置。例如.env
文件内容如下:
VUE_APP_I18N_LOCALE=zh-CN VUE_APP_I18N_FALLBACK_LOCALE=en-US
-
切换语言:
你需要提供一个切换语言的方式,比如一个下拉菜单。当用户选择不同的语言时,你需要更新
i18n.locale
的值。<template> <div> <select v-model="$i18n.locale"> <option value="zh-CN">简体中文</option> <option value="en-US">English</option> </select> <h1>{{ $t('message.hello') }}</h1> <p>{{ $t('message.welcome') }}</p> </div> </template> <script> export default { name: 'LanguageSwitcher' } </script>
这样,当你切换下拉菜单的选项时,页面上的文字就会自动切换到对应的语言。
第三部分:日期格式化
不同国家和地区的日期格式是不一样的。例如,美国习惯使用 "MM/DD/YYYY",而中国习惯使用 "YYYY-MM-DD"。vue-i18n
提供了日期格式化的功能,可以让你根据不同的语言环境显示不同的日期格式。
-
定义日期格式:
在你的语言包文件中,定义日期格式。
en-US.json
:{ "dateFormats": { "short": { "year": "numeric", "month": "short", "day": "numeric" }, "long": { "year": "numeric", "month": "long", "day": "numeric", "weekday": "long" } } }
zh-CN.json
:{ "dateFormats": { "short": { "year": "numeric", "month": "short", "day": "numeric" }, "long": { "year": "numeric", "month": "long", "day": "numeric", "weekday": "long" } } }
这里我们定义了两种日期格式:
short
和long
。 -
使用日期格式化:
在组件中使用
$d
方法来格式化日期。<template> <div> <p>Short Date: {{ $d(date, 'short') }}</p> <p>Long Date: {{ $d(date, 'long') }}</p> </div> </template> <script> export default { name: 'DateFormat', data() { return { date: new Date() } } } </script>
运行你的应用,你应该能看到不同格式的日期。当你切换语言时,日期格式也会自动切换到对应的语言。
第四部分:进阶技巧和注意事项
-
使用命名空间:
如果你的应用比较复杂,语言数据量很大,可以使用命名空间来组织你的语言数据。
// i18n.js import { createI18n } from 'vue-i18n' const i18n = createI18n({ legacy: false, locale: 'zh-CN', fallbackLocale: 'en-US', messages: { 'zh-CN': { app: { name: '我的应用', version: '1.0.0' }, message: { hello: '你好,世界!', welcome: '欢迎来到我的网站!' } }, 'en-US': { app: { name: 'My Application', version: '1.0.0' }, message: { hello: 'Hello, world!', welcome: 'Welcome to my website!' } } } }) export default i18n
在组件中使用:
<template> <div> <h1>{{ $t('app.name') }}</h1> <p>Version: {{ $t('app.version') }}</p> <p>{{ $t('message.hello') }}</p> </div> </template>
-
使用 HTML 标签:
有时候,你需要在翻译文本中使用 HTML 标签,比如链接或者强调文本。
vue-i18n
提供了v-html
指令来实现这个功能。// en-US.json { "message": { "link": "Click <a href="https://www.example.com">here</a> to learn more." } }
<template> <div v-html="$t('message.link')"></div> </template>
注意,使用
v-html
指令需要小心,因为它可能会导致 XSS 攻击。确保你的翻译文本是可信的。 -
处理复数:
不同语言的复数规则是不一样的。例如,英语中,只有一个时使用单数,否则使用复数。而有些语言有更多的复数形式。
vue-i18n
提供了复数处理的功能。// en-US.json { "message": { "apples": "There is {n} apple | There are {n} apples" } }
<template> <div> <p>{{ $t('message.apples', { n: 1 }) }}</p> <p>{{ $t('message.apples', { n: 2 }) }}</p> </div> </template>
-
使用第三方翻译服务:
如果你需要翻译大量的文本,可以考虑使用第三方翻译服务,比如 Google Translate API 或者 DeepL API。
vue-i18n
并没有直接集成这些服务,你需要自己编写代码来实现。 -
测试你的 i18n 代码:
编写单元测试和集成测试来确保你的 i18n 代码能够正常工作。
第五部分:总结
咱们今天聊了 Vue 应用中国际化的方方面面,从基础架构设计到动态加载语言包,再到日期格式化和一些进阶技巧。希望这些内容能帮助你更好地理解和应用国际化技术。
功能 | 描述 |
---|---|
多语言支持 | 支持多种语言,可以根据用户的语言设置显示不同的内容。 |
动态加载 | 语言包可以动态加载,减少初始加载时间。 |
日期格式化 | 可以根据不同的语言环境显示不同的日期格式。 |
命名空间 | 可以使用命名空间来组织语言数据。 |
HTML 标签 | 可以在翻译文本中使用 HTML 标签。 |
复数处理 | 可以处理不同语言的复数形式。 |
第三方翻译服务 | 可以集成第三方翻译服务。 |
测试 | 需要编写单元测试和集成测试来确保 i18n 代码能够正常工作。 |
记住,国际化是一个持续改进的过程。你需要不断地测试和优化你的代码,才能让你的应用真正地走向世界。
最后,祝大家写出更多优秀的国际化应用!下次再见!