什么网站做美食最好最专业,博客网站源码,电子商务网站建设服务外包,北京网站建设 seo公司哪家好痛点
在i18n多语言模块使用过程中#xff0c;发现下面几个问题#xff0c;需要解决
1#xff09;uni-best框架下#xff0c;$t功能函数无法实时的切换语言#xff0c;可能跟使用有关
2#xff09;uni-best建议的translate方式在vue块外使用太繁琐#xff0c;希望不用…痛点
在i18n多语言模块使用过程中发现下面几个问题需要解决
1uni-best框架下$t功能函数无法实时的切换语言可能跟使用有关
2uni-best建议的translate方式在vue块外使用太繁琐希望不用导入直接书写$t使用。统一逻辑减少复杂度
目标
需要完成的目标如下
1将多语言模块放到公共区域可能会导致原生标题无法正常切换语音。这个无所谓因为标题栏已经custom定制并组件化了
2修复无法正常实时切换语言的$t这个可能跟使用方式有关anyway让它能按原模式正常工作
3在任何地方都可以使用$t功能无论是template还是script部分
实现
uni-best的translate方法代码实现了一个很好的思路只是无法支持占位符的功能。让我们改进它
/*** 任意文件使用$t翻译方法需要在app里全局导入* param { string } localeKey 多语言的keyeg: app.name*/
export const translate (localeKey: string, opt: Recordstring, 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.globalProperties._i18n i18n// #endifreturn {app}
}至于在任意位置使用让我们把translate挂载到代码部分的全局
// 安装到全局覆盖不能正常工作的$t
;(function (global) {console.log(install);(global as any).$t translate
})(this || window || globalThis) 下面是最终完成的i18n.ts模块添加了语言切换功能的导出。
API.tools.locale.request是后端的语言切换代码实现前后端语言统一切换目前只导入了3种语言需要其它语言可以自行增加
/*** ccframe i18n模块* 注意由于某种未知的原因uni-best的$t()翻译方法有无法切换语音以及安卓出错的问题因此使用导出的translate方法进行动态翻译* Jim 24/09/20*/import { createI18n } from vue-i18nimport en from /datas/en.json
import zhHans from /datas/zh-Hans.json
import zhHant from /datas/zh-Hant.jsonconst messages {en,zh-Hant: zhHant,zh-Hans: zhHans // key 不能乱写查看截图 screenshots/i18n.png
}const i18n createI18n({legacy: false, // 解决空白报错问题locale: uni.getLocale(), // 获取已设置的语言fallback 语言需要再 manifest.config.ts 中设置messages
})type LocaleType en | zh-Hant | zh-Hansi18n.global.locale.value import.meta.env.VITE_FALLBACK_LOCALE/*** 任意文件使用$t翻译方法需要在app里全局导入* param { string } localeKey 多语言的keyeg: app.name*/
export const translate (localeKey: string, opt: Recordstring, 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 // 转换不了则原样输出
}const langMapper: Recordstring, string {zh-Hans: zh-CN,zh-Hant: zh-TW,en: en-US
}export const setLocale async (locale: LocaleType) {await API.tools.locale.request({ lang: langMapper[locale] })// #ifdef APP-PLUSsetTimeout(() {// 如果是APP需要等待重新启动页面i18n.global.locale.value localeuni.setLocale(locale)}, 300)// #endif// #ifndef APP-PLUSi18n.global.locale.value localeuni.setLocale(locale)// #endif// currentLang.value locale
}// 安装到全局覆盖不能正常工作的$t
;(function (global) {console.log(install);(global as any).$t translate
})(this || window || globalThis)export default i18n/** 非vue 文件使用 i18n
export const testI18n () {console.log(t(app.name))// 下面同样生效uni.showModal({title: i18n 测试,content: t(app.name)})
} */然后就可以简单愉快的使用多语言功能了。
页面上$t(login.enterPhone)根据语言显示“输入手机号码” up-input fontSize32rpx :placeholder$t(login.enterPhone) bordersurround v-modeldata.userMobile styleletter-spacing: 2rpx changedata.mobileErr typenumber maxlength11 / 代码片段这个是form表单验证公共库里的使用 required(error?: string): Validator { this.push({ required: true, validator: (rule: any, val: any, callback: (error?: Error) void) { // 补充验证模式 return val ! undefined val ! null val ! }, message: error ?? (this.labelText ? $t(utils.validator.required) this.labelText : $t(utils.validator.notEmpty)), trigger: [change, blur] }) return this } $t(utils.validator.required)根据语言输出请输入 $t(utils.validator.notEmpty)根据语言输出内容不能为空
完善Typescript类型定义
这样使用起来还有那么一点不舒服就是在script中使用$t时会报错类型找不到红红的一片实际编译没问题。对于代码强迫症人会有点一点受不了那么让这个错误的爆红消失掉
unibest里原本带了i18n.d.ts文件把我们挂载到script全局的定义添加进去
/* eslint-disable no-unused-vars */
export {}declare module vue {interface ComponentCustomProperties {$t: (key: string, opt?: Recordstring, any) string// $tm: (key: string, opt?: Recordstring, any) [] | { [p: string]: any }}
}declare global {function $t(localeKey: string, opt?: Recordstring, any): string
}刷新一下vscode不爆红了完美~