uniapp中,小程序、app环境国际化时,传递参数不生效的曲线救国方式
2024/04/21, uniapp, unibest 2.0.0
摘要:uniapp中,小程序、app环境国际化时,传递参数不生效的曲线救国方式
背景
//语系维护:
en: {
message: {
weight: '{0} kg',
}
}
$t('weight',['100'])
-> 期望:100 kg
,实际(小程序、app中): kg
或者 {0} kg
原因:大致分析是由于$t
方法在小程序、app中会丢失带{}的参数
曲线救国的方式
1.自己写方法根据 key、当前语言 去获取对应的语言文本 (保证取出来的文本不会丢失 {0}参数)
// 代码参考unibest-i18n分支 locale/index.ts 中
export const translate = (localeKey: string) => {
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)) {
return message[localeKey]
}
return localeKey
}
2.自己写方法去替换文本中的参数
// formatString('已阅读并同意{0}和{1}','用户协议','隐私政策') -> 已阅读并同意用户协议和隐私政策
export function formatString(template: string, ...values: any) {
console.log(template, values)
// 使用map来替换{0}, {1}, ...等占位符
return template.replace(/{(\d+)}/g, (match, index) => {
const value = values[index]
return value !== undefined ? value : match
})
}
最终使用效果
// 原生使用效果(小程序、app中不生效): $t('weight',['100'])
formatString(translate('weight'),'100')
注意
这个方法只支持参数内容为 {0} {1} ... 这样的形式,不支持 {heavy} {param}这种具名化的参数形式,方案不能算完美,不过可以继续修改formatString方法,思路是 formatString('{heavy} kg',{'heavy':'100}) ,第二个参数形式是 {'heavy':'100'} 对象格式,然后遍历这个对象取出每一个 key value,将字符串中的 {key} 替换为 value 即可