需求背景介绍
现在有大量的外国客户会使用到我们的产品,从而产生了需要有通过切换语种达到显示不同语种文案的页面,用来满足外国客户的浏览使用。而如今市面上有很多流行的第三方库,可以实现这种能力,如vue-i18n。而微信原生小程序的运行环境是将WebViewe与AppService分层处理,所以需要自研一套支持在微信原生小程序技术框架上运行的i18n库。
设计概要
主要模块。
- 实现一个下载进程器。保证多个相同的CDN请求时,只发一条CDN的正常下载。
- 实现一个观察者,用于在异步数据响应成功后通知相关的页面或组件进行更新。
- 实现一个缓存器,用于将CDN上获取的语言包内容缓存起来,避免重复请求。
- 实现一个i18n类,主要用于实例后的对外api整理。
- 实现一个package类,主要用于集成下载进程器、观察者、缓存器及实例后的api整理。
- WXS(微信脚本),这个模块主要是实现i18n.t方法及与AppService层的通信。
主要的功能
i18n库提供install方法,用于集成在RPRM或未来的其它平台上。install方法返回一个i18n实例,该实例内置以下属性:
方法 | 作用描述 | 参数 | 备注 |
---|---|---|---|
data | 所有缓存的模块语言包内容,按package名分包。如:wx.rprm.i18n.data.package1 wx.rprm.i18n.data.package2 |
不涉及 | 只缓存当前语种的语言包内容。 |
getCurrentLang() | 获取当前语种的函数。 | 无 | |
swtich({lang}) | 全量切换语种。 | {lang:string} | |
use(options} | 预加载模块语种 | {package:string,version:string/number} | |
globalConfig(config) | 通过路由划分,实现全量配置模块描述。 | object |
开发者希望使用的方式
//语法
i18n.t('key','default',options:object|array)
//具名格式
//对应的语言包格式
...
spec:'规格:{num}个'
...
//I18n.t的使用方式
...
{{i18n.t('spec',{num:'100'})}}
...
//结果
//规格:100个
//列表格式
//对应的语言包格式
...
spec:'规格:第{0}百零{1}个'
...
//I18n.t的使用方式
...
{{i18n.t('spec', ['一','三'])}}
...
//结果
//规格:第一百零三个
WXS(微信脚本)
由于i18n库涉及的模块比较多,所以这里说明WXS(微信脚本)模块是如何实现t方法及与AppService层实现通信能力。
如何在WXML上使用i18n.t方法
WXML上无法直接使用方法,所以要借助微信脚本(WXS)完成。声明一个WXS文件,在里面实现t方法,然后在WXML中引入这个WXS文件,其module的值设置为i18n。参考代码:
//WXS
function t(参数){
//实现功能
}
module.exports = {t}
//WXML
<wxs src='路径/名称.wxs' module='i18n'></wxs>
<view>{{i18n.t(参数)}}</view>
如何在微信脚本(WXS)上得到语言包内容
微信脚本(WXS)是WebView里的一个脚本,想得到AppService里的数据,是需要实现数据通信的能力。借助setData触发微信脚本(WXS)的WxspropObserver。
参考代码:
<wxs src='路径/名称.wxs' module='i18n'></wxs>
<view change:prop="{{i18n.change}}" prop="{{langs}}"></view>
//WXS
function t(参数){
//实现功能
}
function change(langs){
//langs参数就是AppService层的setData传递的值
}
module.exports = {t}
上述代码的基本思路是,在view元素上的属性值绑定AppService层中data中的langs。用setData触发langs更新到Webview层的view元素上,然后用WxsPropObserver监听prop是否发生变化,变化了就触发i18n脚本模块中的change方法。change方法触发后会得到prop的值,也就是langs的值。
t方法格式化
...
/**
* 格式化列表
* 场景二:”Hello,{0}{1} = "Hello,world!"
*
*/
var formatterByList = function(text, list = []) {
//遍历数组
//利用正则将花括号内容捕获匹配的内容替换成对应下标的数组值。
return text;
};
/**
* 具名格式化
* 场景一:"Hello,{msg}" = "Hello,world“
*
*/
var formatterByName = function(text, names = {}) {
//利用正则分析出花括号里的值
//在names对象里找到花括号里值的内容
return text;
};
...
总结
上述主要是说明如何在WXML使用t方法以及将语言包内容同步到微信脚本上。实际的项目中需要考虑到将i18n功能模块化,异步数据获取监听及通知到微信脚本,性能、缓存等问题。
miniprogram-i18n-plus 个别机型上会加载不到,大家有遇到过这个问题吗
大体按照大佬的思路实现了一下,欢迎 start
微信小程序国际化解决方案:https://github.com/hefeng6500/miniprogram-i18n-plus
特点:开箱即用,相比官方 miniprogram-i18n 使用更加方便,不需要使用 glup 进行构建
官方 i18n miniprogram-i18n,不知道动态加载数据,locales 只能定义在静态文件里面,miniprogram-i18n-plus 就可以完美的支持异步数据动态加载。