在使用vue-i18n进行国际化切换时,我们需要把整个系统的或者当前页面所涉及到的中文字符进行翻译,并替换为i18n所执行的字符形式。本文主要目的就是快速,半自动对当前页面的进行翻译,生成中英文配置对象,并替换当前页面的所有中文。以下是实现步骤(不包含全部源码):
1、提取中文字符
let reg = /(?<!(\/\/|\*|\<\!\-\-).*)[a-zA-Z0-9()]*[\u4e00-\u9fa5]{2,}[a-zA-Z0-9(),:\u4e00-\u9fa5\-]*[\:\:\?\?!]?/g;
let allzh = input.match(reg) || [];
以上正则表达式,主要是排除相关注释内容,匹配出带有:、?等的中文语句。此表达式可能会有部分问题,使用时需根据实际所需进行修改优化。
2、翻译中文字符
本文翻译中文字符,使用的是免费的百度翻译api,可自行去官网申请并使用。
translate(str).then((item) => {
let dst = item;
let enArr = dst.split("_ ");
for (let i = 0; i < enArr.length; i++) {
let arr = enArr[i].toLowerCase().split(" ");
arr = arr.map((item: string, index: number) => {
if (index !== 0) {
return item.replace(/^./g, item.charAt(0).toUpperCase());
} else {
return item;
}
});
let resKey = arr
.join("")
.replace(":", "Col")
.replace(/\(.*\)/g, "")
.replace(/[,,!\!\-\?]/g, "");
res[resKey] = arrParam[i];
}
resolve(res);
});
翻译完之后,把翻译的字符串改成驼峰形式,并作为对象的key值,对象的value值为之前提取的中文字符串。
3、中文对象转换成英文对象
该步骤主要用于,对已经产生的中文配置对象进行转换,并生成value值为英文的对象。该步骤也可在第二部步中生成。
function zhObjToEn(obj: {
[key: string]: string;
}): Promise<{ [key: string]: string }> {
return new Promise((resolve, reject) => {
let res = { ...obj };
let tranStr = Object.values(obj).join("_");
translate(tranStr).then((data) => {
let enArr = data.split("_ ");
Object.keys(res).forEach((item, index) => {
res[item] = enArr[index];
});
resolve(res);
});
});
}
4、替换中文字符
根据生成的配置对象,对当前页面的符合标准的中文字符串进行全局替换。下面的正则表达式只包含了部分情况,具体写法可按照实际情况进行优化补充。
function toReplace(
str: string,
obj: { [key: string]: string },
moduleName: string
): string {
Object.entries(obj).forEach(([key, value]) => {
// 不匹配注释内容 ,同时解决父串包含子串被子串替换的问题
let reg = new RegExp(
String.raw`(?<![\"\'\u4e00-\u9fa5]|(\/\/|\*).*)${value}(?!.*[\"\'\*\u4e00-\u9fa5])`,
"g"
);
// 匹配 "" , ''内容
let reg1 = new RegExp(String.raw`(?<!=)[\"\']${value}\?*[\"\']`, "g");
str = str
.replaceAll(`label="${value}"`, `:label="$t('${moduleName}.${key}')"`)
.replaceAll(`title="${value}"`, `:title="$t('${moduleName}.${key}')"`)
.replaceAll(
`placeholder="${value}"`,
`:placeholder="$t('${moduleName}.${key}')"`
)
.replaceAll(reg, `{{$t('${moduleName}.${key}')}}`);
str = str.replaceAll(reg1, `this.$t('${moduleName}.${key}')`);
});
return str;
}
为方便操作,前期可以使用node.js中的fs模块,读取vue文件中的内容,并把替换完成的字符串写到新的文件(此处可能需要手动复制粘贴)。
基本的流程就是这些,有什么优化欢迎补充~。
后续会出现Vs Code插件版本,敬请期待!