国际化是什么?
国际化 对应的英文单词为 Internationalization,又称 i18n
:
i
为单词的 【第一个】 字母18
为 【i
和n
之间】 单词的个数n
代表这个单词的 【最后一个】 字母
如果你的项目是 Vue
,那么相信你在实现国际化功能时,也必不可少的会使用到 vue-i18n
这个库,接下来本文也是通过这个库搭配 Vue
实现最基本的国际化功能,但关注点并不是如何使用这个库,而是在实现的过程中思考 可优化的点。
实现基本国际化功能
这里就不再多余演示 demo
项目的创建过程了,并且文中只演示最基本的 中英文 切换,好了现在直奔核心吧!
集成 vue-i18n
安装依赖
熟悉的命令:npm install vue-i18n -S
配置 vue-i18n
- 在
src
目录下创建language
目录用于保持和语言切换相关的内容 - 在
language
目录下创建lang
目录用于保存不同语言的映射关系,如中文对应zh.js
、英文对应en.js
等 - 在
language
目录下创建index.js
作为默认导出,并在其中创建i18n
对象
import { createI18n } from "vue-i18n"; import zh from './lang/zh'; import en from './lang/en'; const i18n = createI18n({ legacy: false, locale: "zh", // 初始化配置语言 messages: { zh, en, }, }); export default i18n; 复制代码
main.js 注册 i18n
内容非常简单,直接上代码:
import { createApp } from "vue"; import i18n from "./language"; import store from "./store"; import App from "./App.vue"; createApp(App) .use(store) .use(i18n) .mount("#app"); 复制代码
实际上在通过 use(i18n)
时,会调用 i18n.install()
方法,大概内容如下:
- 通过
app.provide(app.__VUE_I18N_SYMBOL__, i18n)
将i18n
对象提供给应用中的所有后代组件可通过inject
注入 - 通过
app.config.globalProperties.xxx = xxx
的方式为应用添加 全局属性/方法,实际上是对Vue2
中Vue.prototype
使用方式的一种替代
- 常见全局属性,如
$i18n
通过app.config.globalProperties.$i18n = i18n
添加到全局 - 常见全局方法,如:
$t, $rt, $d, $n, $tm
通过Object.defineProperty(app.config.globalProperties, `$${method}`, desc)
添加到全局
- 通过
aplly(...)
方法注册常用的 全局指令v-t
和 全局组件i18n
等 - 在根组件卸载时移除/释放
i18n
相关内容
const unmountApp = app.unmount; app.unmount = () => { i18n.dispose(); unmountApp(); }; 复制代码
- 注册
vue-devtools
的相关插件
根据数据信息填充国际化内容
页面渲染
假设需要渲染如下数据对应的列表,并且要实现国际化:
const data = [ { url: vueImg, title: 'Vue', describe: '渐进式 JavaScript 框架' }, { url: reactImg, title: 'React', describe: '用于构建用户界面的 JavaScript 库' }, { url: angularImg, title: 'Angular', describe: '现代 Web 开发平台' }, { url: nodeImg, title: 'Node', describe: 'Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时' }, { url: webpackImg, title: 'Webpack', describe: 'webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具' }, ]; 复制代码
对应 App.vue
组件模板内容如下:
<template> <button class="btn" @click="changeLang">{{ $t("中/英") }}</button> <List :data="data" /> </template> 复制代码
对应的页面效果如下:
填充 lang 目录下映射关系
在 lang/zh.js
文件中:
export default { "渐进式 JavaScript 框架": "渐进式 JavaScript 框架", "用于构建用户界面的 JavaScript 库": "用于构建用户界面的 JavaScript 库", "现代 Web 开发平台": "现代 Web 开发平台", "Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时": "Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时", "webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具": "webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具", "中/英": "中/英", }; 复制代码
在 lang/zh.js
文件中:
export default { "渐进式 JavaScript 框架": "Progressive JavaScript framework", "用于构建用户界面的 JavaScript 库": "JavaScript library for building user interface", "现代 Web 开发平台": "Modern web development platform", "Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时": "Node.js is a JavaScript runtime based on the chrome V8 engine", "webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具": "Webpack is a static module packaging tool for modern JavaScript applications", "中/英": "Chinese / English", }; 复制代码
在 <List />
组件中进行翻译处理
翻译处理可通过如下方式处理:
- 使用
$t(...)
方法 - 使用
v-t
指令 - 使用
<i18n-t></i18n-t>
组件
这里选择第一种,因为它更灵活,能使用的范围也更广,指令和组件形式限定在了 template
中:
效果演示