北京微信网站建设报价手机网站pc网站
- 作者: 五速梦信息网
- 时间: 2026年03月21日 10:06
当前位置: 首页 > news >正文
北京微信网站建设报价,手机网站pc网站,wordpress响应式博客主题,会计招聘背景
有一个vue项目#xff0c;要实现国际化功能#xff0c;能够切换中英文显示#xff0c;因为该项目系统的用户包括了国内和国外用户。
需求
1、页面表单上的所有中文标签要国际化#xff0c;包括表单属性标签、表格列头标签等#xff0c; title“数量”#xff1b;…背景
有一个vue项目要实现国际化功能能够切换中英文显示因为该项目系统的用户包括了国内和国外用户。
需求
1、页面表单上的所有中文标签要国际化包括表单属性标签、表格列头标签等 title“数量”
2、输入框的提示内容需要国际化如 placeholder“选择日期”
3、js代码中的提示信息需要国际化如 message(“请勾选批量设置”)、confirm(‘您确定要设置业务损耗吗’、title: ‘删除错误’ 等
解决方案
1、开发流程一开始开发过程中我们不考虑国际化等代码基本完成后最后再进行国际化
2、考虑日后还可能由其他语种所以这里我们做国际化词语库时国际化编码使用5位数字对应多种语言值即一对多
3、前端我们重新封装一个全局方法 \(lang(param1, param2) 来支持国际化param1是国际化编码param2是默认值如果国际化编码没找到对应的语言单词则默认用param2且去掉左右两边的 ‘~’符号
其实后来又分析了下如果一开始前端开发人员把所有需要国际化的中文词语都写成 \)lang(‘中文词语’) \(lang方法逻辑再修改下如果没有第二个参数并且第一个参数对应的国际化词语也没有则直接显示第一个参数字符串而且这样的话到后面再提取代码中的需要国际化的内容时就会很精确了。
4、国际化流程
从前端代码文件中将所有的中文提取出来形成一个数组放到一个json文件中并且数组需要去重一下使用第三方的翻译接口来对导出的中文进行翻译生成一个中英文对照键值对json文件校对中英文对照表因为有的翻译不一定准确根据校对后的中英文对照表生成国际化编码库并创建两个国际化文件根据校对后的中英文对照表并分析代码规则将程序代码中的中文进行国际化处理
国际化流程实施
在国际化流程实施中我使用编写js脚本代码来实现相关的处理使用node环境来执行脚本
1、提取中文
从前端代码文件中将所有的中文提取出来形成一个数组放到一个json文件中并且数组需要去重一下
下面的代码是用来提取文件代码中的中文的我们可以将代码文件命名为extractChinese.js使用node来执行该脚本
代码中要国际化的路径设置的是当前目录下的src下的 components和pages文件夹
const fs require(fs);
const path require(path);
const chineseRegex /[一-龥]/g; function extractChineseFromFile(filePath) { const content fs.readFileSync(filePath, utf-8); const chineseWords content.match(chineseRegex); return chineseWords || [];
} function processDirectory(directoryPath) { const files fs.readdirSync(directoryPath); const chineseSentences []; files.forEach((fileName) { const filePath path.join(directoryPath, fileName); const stats fs.statSync(filePath);if (stats.isDirectory()) { chineseSentences.push(...processDirectory(filePath)); } else if (stats.isFile() [.js, .vue].indexOf(path.extname(filePath)) -1) {const chineseWords extractChineseFromFile(filePath); chineseSentences.push(...chineseWords); } }); return chineseSentences;
} function main() { const srcDirectory path.join(__dirname, src); const componentsDirectory path.join(srcDirectory, components); const pagesDirectory path.join(srcDirectory, pages); const componentsChineseSentences processDirectory(componentsDirectory); const pagesChineseSentences processDirectory(pagesDirectory); const allChineseSentences [...componentsChineseSentences, ...pagesChineseSentences]; //const allChineseSentences componentsChineseSentences; const outputPath path.join(__dirname, output.json); // 使用 Set 对象来去重 let backString Array.from(new Set(allChineseSentences)); // 对去重后的数组进行排序 backString.sort();fs.writeFileSync(outputPath, JSON.stringify(backString, null, 2), utf-8); console.log(提取到的中文单词或语句已保存到output.json文件中。);
} main();2、翻译中文
使用第三方的翻译接口来对导出的中文进行翻译生成一个中英文对照键值对json文件
翻译接口这里我们用的是百度翻译至于如何去使用百度翻译这里就不再说了自己去百度看吧;
该步骤需要用到第一步生成的 output.json 文件然后翻译结果是存在 translated_zh_en.json 中。
const fs require(fs);
const axios require(axios);
const appId 123456789; // 替换成你的百度翻译的APP ID
const secretKey 999999999; // 替换成你的百度翻译的密钥 const crypto require(crypto);
axios.defaults.headers.post[Content-Type] application/x-www-form-urlencoded;charsetUTF-8;function md5Hash(input) { // 创建一个哈希对象 const hash crypto.createHash(md5); // 更新哈希对象的内容 hash.update(input); // 获取哈希值的二进制表示 const hashBuffer hash.digest(); // 将二进制转换为十六进制表示 const hashHex hashBuffer.toString(hex); // 返回小写的哈希值 return hashHex.toLowerCase();
} // 使用百度翻译API进行翻译
async function translateToEnglish(text) { const params { q: text, appid: appId, salt: Date.now(), from: zh, to: en, sign: };// 计算签名 params.sign md5Hash(params.appid params.q params.salt secretKey);// 请求翻译 const url http://api.fanyi.baidu.com/api/trans/vip/translate?q\){encodeURIComponent(params.q)}fromzhtoenappid\({params.appid}salt\){params.salt}sign\({params.sign};const response await axios.get(url); //console.log(url);//console.log(response.data)// 返回翻译结果 return response.data.trans_result[0].dst;
} function sleep(ms) { return new Promise(resolve setTimeout(resolve, ms));
} async function mysleep() { console.log(休息1秒......................); await sleep(1000); // 暂停 1 秒 console.log(休息完成...);
} async function process() { // 读取json文件 const data JSON.parse(fs.readFileSync(output.json, utf8)); // 存储翻译结果的对象 let translationData {}; let execNumber 1;// 遍历中文字符串数组进行翻译for (let i 0; i data.length; i) { const chineseString data[i]; const englishString await translateToEnglish(chineseString); // 将原中文字符串和英文字符串形成键值对存储到translationData对象中 translationData[chineseString] englishString;if (execNumber 120) { // 如果不想全部执行则执行多少场退出break;} else if (i execNumber*20) { // 每执行20次接口调用就休息1秒execNumber;await mysleep()}}// 将翻译结果写入translate.json文件中 fs.writeFileSync(translated_zh_en.json, JSON.stringify(translationData, null, 2));
} process().catch(error { console.error(error);
});3、校对翻译
校对中英文对照表因为有的翻译不一定准确找个行业英语水平高点的人自己去校对吧
4、创建国际化库
根据校对后的中英文对照表生成国际化编码库并创建两个国际化文件
const fs require(fs); // 读取原始 JSON 文件
const data JSON.parse(fs.readFileSync(translated_zh_en.json, utf8)); // 中文和英文的 JSON 文件
const chineseData {};
const englishData {}; let serialNumber 00001; // 遍历原始数据生成新的键值对
for (let chinese in data) { const english data[chinese]; // 生成新的键值对序号为 5 位数字 const key N\){String(serialNumber).padStart(5, 0)}; chineseData[key] chinese; englishData[key] english; serialNumber;
} // 将中文和英文的 JSON 数据写入文件
fs.writeFileSync(cn.json, JSON.stringify(chineseData, null, 2));
fs.writeFileSync(en.json, JSON.stringify(englishData, null, 2));5、代码国际化处理
根据第4步生成的中文国际化文件 cn.json 并分析代码规则将程序代码中的中文进行国际化处理
首先要分析程序需要国际化的代码规则因为这个替换不是简单的去就把中文替换可能代码都由变化我们分析项目代码中目前的规则如下
场 景
代码示例**
查找内容**
替换内容**
作为组件元素内容的
vxe-button clickcloseModel取消/vxe-button span stylecolor: red;如调整了颜色尺码保存后请务必核对检查数量和配色数据!/span div classtitle尺码信息/div
取消
{{\(lang(‘10000’, ‘取消’)}}
作为组件元素属性值的
vxe-table-column fieldodgc_pcs title数量 width100 header-aligncenter alignright el-date-picker v-ifrow.type date typedate placeholder选择日期 v-modelrow.value
title数量placeholder“选择日期”
:title“ l a n g ( ′ 1000 1 ′ , ′ 数量 ′ ) : p l a c e h o l d e r lang(‘10001’, ‘数量’)“:placeholder” lang(′10001′,′数量′):placeholderlang(‘Ph_select_data’, ‘选择日期’)”
组件模板代码中三元运算结果
el-button sizemini clickalterConsumption(row){{onlyShow?查看:修改}}/el-button
‘查看’:‘查看’ ::‘修改’: ‘修改’
l a n g ( ′ 1000 2 ′ , ′ 查看 ′ ) 同上 lang(‘10002’, ‘查看’)同上 lang(′10002′,′查看′)同上lang(‘10003’, ‘修改’)同上
js 中方法参数值
this.\)XModal.message(请勾选批量设置, error); this.\(XModal.confirm(您确定要设置吗) this.\)confirm(确定要删除此记录吗 , 提示, { confirmButtonText: 确定, cancelButtonText: 取消, type: warning, })
message(请勾选批量设置message(请勾选要批量设置’confirm(您确定要设置吗confirm(‘您确定要设置吗’“提示”,confirmButtonText: “确定”,cancelButtonText: “取消”,
message(this. l a n g ( ′ 1000 4 ′ , ′ 请勾选批量设置 ′ ) 同上 c o n f i r m ( t h i s . lang(‘10004’, ‘请勾选批量设置’)同上confirm(this. lang(′10004′,′请勾选批量设置′)同上confirm(this.lang(‘10005’, ‘您确定要设置吗’)同上this. l a n g ( ′ 1000 6 ′ , ′ 提示 ′ ) , c o n f i r m B u t t o n T e x t : t h i s . lang(‘10006’, ‘提示’),confirmButtonText: this. lang(′10006′,′提示′),confirmButtonText:this.lang(‘10007’, ‘确定’)cancelButtonText: this.\(lang(‘10008’, ‘取消’)
js 中对象属性赋值
this. X M o d a l . m e s s a g e ( m e s s a g e : 保存失败 , s t a t u s : e r r o r ) ; t h i s . XModal.message({ message: “保存失败”, status: “error” }); this. XModal.message(message:“保存失败”,status:“error”);this.message({ message: ‘请选择要设置的物料!’, type: ‘warning’ }); this. X M o d a l . a l e r t ( m e s s a g e : 请选择附件分类 , s t a t u s : w a r n i n g , ) ; t h i s . XModal.alert({ message: “请选择附件分类”, status: “warning”, }); this. XModal.alert(message:“请选择附件分类”,status:“warning”,);this.XModal.alert({ status: “error”, title: “删除错误”, message: response.msg
“服务器删除发生错误”, });
js 中 || 赋值
this.\)XModal.alert({ status: “error”, title: “删除错误”, message: response.msg
“服务器删除发生错误”, });
替换的脚本代码如下
const fs require(fs);
const path require(path);// 读取 cn.json 文件并解析 JSON 数据
function loadTranslations() {const cnJsonPath path.join(dirname, src, lang, cn.json);const content fs.readFileSync(cnJsonPath, utf-8);return JSON.parse(content);
}// 判断字符串是否以指定前缀开头
function startsWith(str, prefix) {return str.startsWith(prefix);
}/*** 每个键值对的场景匹配* param {String} fileContent 文件内容* param {String} key 国际化变量名* param {String} value 中文字符串*/
function replaceAllScene(fileContent, key, value) {// 场景取消let searchValue \({value};let replaceValue {{\)lang(\({key}, ~\){value}~)}};fileContent fileContent.split(searchValue).join(replaceValue); // 场景title数量searchValue title\({value};replaceValue :title\)lang(\({key}, ~\){value}~);fileContent fileContent.split(searchValue).join(replaceValue);// 场景placeholder选择日期searchValue placeholder\({value};replaceValue :placeholder\)lang(\({key}, ~\){value}~);fileContent fileContent.split(searchValue).join(replaceValue);// 场景message(请勾选批量设置searchValue message(\({value};replaceValue message(this.\)lang(\({key}, ~\){value}~);fileContent fileContent.split(searchValue).join(replaceValue);// 场景message(请勾选批量设置searchValue message(\({value};replaceValue message(this.\)lang(\({key}, ~\){value}~);fileContent fileContent.split(searchValue).join(replaceValue);// 场景confirm(您确定要设置业务损耗吗searchValue confirm(\({value};replaceValue confirm(this.\)lang(\({key}, ~\){value}~);fileContent fileContent.split(searchValue).join(replaceValue);// 场景confirm(您确定要设置业务损耗吗searchValue confirm(\({value};replaceValue confirm(this.\)lang(\({key}, ~\){value}~);fileContent fileContent.split(searchValue).join(replaceValue);// confirmButtonText: 确定,searchValue confirmButtonText: \({value},;replaceValue confirmButtonText: this.\)lang(\({key}, ~\){value}~),;fileContent fileContent.split(searchValue).join(replaceValue);// cancelButtonText: 取消,searchValue cancelButtonText: \({value},;replaceValue cancelButtonText: this.\)lang(\({key}, ~\){value}~),;fileContent fileContent.split(searchValue).join(replaceValue);// message: 保存失败searchValue message: \({value};replaceValue message: this.\)lang(\({key}, ~\){value}~);fileContent fileContent.split(searchValue).join(replaceValue);// message: 保存失败searchValue message: \({value};replaceValue message: this.\)lang(\({key}, ~\){value}~);fileContent fileContent.split(searchValue).join(replaceValue);// title: 删除错误searchValue title: \({value};replaceValue title: this.\)lang(\({key}, ~\){value}~);fileContent fileContent.split(searchValue).join(replaceValue);// title: 删除错误searchValue title: \({value};replaceValue title: this.\)lang(\({key}, ~\){value}~);fileContent fileContent.split(searchValue).join(replaceValue);return fileContent;
}// 在给定文件中替换指定的字符串
function replaceStringsInFile(filePath, replacements) {const content fs.readFileSync(filePath, utf-8);let newContent content;for (const [key, value] of Object.entries(replacements)) {// 如果匹配到的字符串前面存在 message(则去掉左右两边的双引号 //const searchValue startsWith(value, message() ? value.slice(8, -1) : value;newContent replaceAllScene(newContent, key, value);//newContent newContent.split(searchValue).join(\(lang( key ,) searchValue );}if (newContent ! content) {fs.writeFileSync(filePath, newContent, utf-8);console.log(Replaced strings in \){filePath});}
}// 在指定目录下处理所有文件
function processDirectory(directoryPath, replacements) {const files fs.readdirSync(directoryPath);files.forEach((fileName) {const filePath path.join(directoryPath, fileName);const stats fs.statSync(filePath);if (stats.isDirectory()) {processDirectory(filePath, replacements);} else if (stats.isFile()) {replaceStringsInFile(filePath, replacements);}});
}function main() {const translations loadTranslations();const componentsDirectory path.join(dirname, src, components);const pagesDirPath path.join(__dirname, src, pages);processDirectory(componentsDirectory, translations);processDirectory(pagesDirPath, translations);
}main();到此我们就完成了前端代码的国际化实现
我们为什么要把原中文作为 国际化方法 \(lang 的第二个参数呢
因为如果代码文件中看不到中文修改代码的时候太难找了你只能看到国际化数字编码。
建议
建议是在前端一开始开发的时候就把需要国际化的地方都写成 \)lang(‘中文’)包括模板代码和js代码中
这样后期替换更精确而且一开始开发人员也不用去管国际化
并且我们在提取代码中文时就可以按 \(lang(‘中文’) 这个格式精确提取了国际化处理后就变成 \)lang(‘国际化编码’,‘中文’) 这样我们在第二次再提取时就不会重复提取已经国际化处理后的代码中文了。
相关文章
-
北京微信网站搭建费用用wordpress 帮客户建站
北京微信网站搭建费用用wordpress 帮客户建站
- 技术栈
- 2026年03月21日
-
北京微网站建设设计服务商开发公司交房归物业公司交给物业公司
北京微网站建设设计服务商开发公司交房归物业公司交给物业公司
- 技术栈
- 2026年03月21日
-
北京微网站建设建设银行互联网网站
北京微网站建设建设银行互联网网站
- 技术栈
- 2026年03月21日
-
北京微信网站建设电话上海自贸区注册公司的好处和坏处
北京微信网站建设电话上海自贸区注册公司的好处和坏处
- 技术栈
- 2026年03月21日
-
北京鲜花的网站建设电商具体是做什么的上班
北京鲜花的网站建设电商具体是做什么的上班
- 技术栈
- 2026年03月21日
-
北京响应式的网站公司组织架构图模板
北京响应式的网站公司组织架构图模板
- 技术栈
- 2026年03月21日






