千里之行,始于足下
声明
本篇文章的源代码基于开源组件库 vant
需求分析
在开始实现功能之前我们先来看下,通用的i18n库的使用流程,如下所示:
从上图可知,要想使用i18n得先导入这个包,然后使用Vue.use
方法去install这个包,再进行初始化i18n实例,最后在new Vue
的时候挂载到全局。
所以我们设计的时候需要提供一个 install
方法,用于初始化,也需要提供 locale
和 messages
去标记当前语言类型和具体的语言对应的内容,最后挂载到Vue的全局实例上。继续往下走 -↓
设计实战
实现细节如下所示:
- 定义一个
install
方法,用于初始化。在这个方法中我们创建2个挂载在Vue原型上的响应式对象,如下所示:
1 | import defaultMessages from './lang/zh-CN' // 对应的默认语言包 |
从上可知,定义了2个私有属性 $prefixLang
(对应locale) 和 $prefixMessages
(对应messages) (注意为变量名带上自定义的 prefix
) 在Vue的原型上,这样就达到了挂载到全局的目的,但是为了能够使之变为可响应式的对象,还需要利用 Vue.util.defineReactive
方法(这个方法没有在官网上暴露,需要通过分析源码时获知,更具体的解释见→附录←)
- 定义一个
use
方法进行语言的切换。如下所示:
1 | import deepAssign from '../utils/deep-assign' |
从上可以,我们可以通过 use
方法并配合 deepAssign
方法 来进行当前语言和对应的内容的切换, deepAssign
的实现细节见 →附录←
- 为了能够在Vue组件模板中使用,同样需要创建一个
$t
函数,如下所示:
1 |
|
从上可知,创建了一个可混入的 $t
computed 属性, 然后在对应的Vue文件上使用 mixins
的方式混入(更多源码),这样我们就能在Vue组件模板上使用 $t
函数来做国际化了,如下所示:
1 | <template> |
至此,如何实现国际化已经全部分析完毕。
- Vue.util 源码定义见 Vue.util
- defineReactive 源码分析见 Vue.util.defineReactive
- deepAssign 源码分析见 deepAssign