痛点
在i18n多语言模块使用过程中,发现下面几个问题,需要解决
1)uni-best框架下,$t功能函数无法实时的切换语言,可能跟使用有关
2)uni-best建议的translate方式在vue块外使用太繁琐,希望不用导入,直接书写$t使用。统一逻辑,减少复杂度
3)uniapp默认的多语言模式在APP下会重启,造成的体验不好
目标
需要完成的目标如下
1)将多语言模块放到公共区域,可能会导致原生标题无法正常切换语音。这个无所谓,因为标题栏已经custom定制并组件化了
2)修复无法正常实时切换语言的$t,这个可能跟使用方式有关,anyway,让它能按原模式正常工作
3)在任何地方都可以使用$t功能,无论是template还是script部分
4)不用重启直接刷新界面
实现
uni-best的translate方法代码实现了一个很好的思路,只是无法支持占位符的功能。让我们改进它
/**
* 任意文件使用$t翻译方法,需要在app里全局导入
* @param { string } localeKey 多语言的key,eg: "app.name"
*/
export const translate = (localeKey: string, opt: Record<string, any> = {}) => {
if (!localeKey) {
console.error(`[i18n] Function translate(), localeKey param is required`)
return ''
}
const locale = uni.getLocale()
const message = messages[locale]
if (Object.keys(message).includes(localeKey)) {
const template = message[localeKey]
// 使用 Object.keys 遍历 params 对象,替换模板中的大括号占位符
return Object.keys(opt).reduce(
(acc, key) => acc.replace(new RegExp(`{${key}}`, 'g'), opt[key]),
template
)
}
return localeKey // 转换不了则原样输出
}
然后在main.ts里把它挂载到全局
import { message, alert, confirm, translate } from '@/utils'
...
export function createApp() {
const app = createSSRApp(App)
...
app.use(i18n)
app.config.globalProperties.$t = translate // 覆盖不能正常工作的$t函数
// #ifdef MP-WEIXIN
// 由于微信小程序的运行机制问题,需声明如下一行,H5和APP非必填
app.config.glob