vue指令实现数字和大写中文实时互转
作者:JYeontu
说在前面
最近在做一个需求,需要在用户输入数字失焦后实时将数字转为大写中文,聚焦的时候将大写中文转为数字以便用户继续修改。这里我们可以封装一个通用指令来做转换,接下来就让我们一起来实现一个转换指令吧。
效果展示

体验地址
jyeontu.xyz/jvuewheel/#/JNumberToChineseWordsView

实现思路
1、数字转大写中文
首先我们需要先实现一个函数,将数字转为大写中文的形式。
(1)函数入参
const numberToChineseWords = (num, unit = "元", append = "整") => {...};
1.num
必出参数,默认值为 “元”,需要进行转换的数字。
2.unit
可选参数,默认值为 “元”,用于指定整数金额部分后面跟随的单位字符。通过设置这个参数,可以根据不同的业务场景或语言习惯需求来改变金额单位的显示,比如在某些特定财务报表中可能需要显示为 “圆” 等情况,就可以传入相应的字符作为该参数的值进行自定义。
3.append
可选参数,默认值为 “整”,用于在金额为整数时,在转换后的中文金额表述后面追加的字符。比如常见的整数金额书写规范中会添加 “整” 字表示没有小数部分,若不需要这个追加字符或者有其他业务特定的追加内容要求,可以通过修改该参数来实现。
(2)辅助常量
用于辅助完成数字到中文的转换。
// 汉字的数字 const cnNums = ["零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"]; // 基本单位 const cnIntRadice = ["", "拾", "佰", "仟"]; // 对应整数部分扩展单位 const cnIntUnits = ["", "万", "亿", "兆"]; // 对应小数部分单位 const cnDecUnits = ["角", "分", "毫", "厘"]; // 最大处理的数字 const maxNum = 9999999999999999.99;
(3)输入参数合法性检查与预处理
- 首先对传入的 num 参数进行空字符串检查,如果为空,则直接返回空字符串,避免后续不必要的处理。
- 若转换后的金额大于 maxNum,超出了函数能够合理处理的范围,同样返回空字符串,确保函数的稳定性和正确性。
- 对于金额为 0 的特殊情况,直接按照设定的格式(使用默认或传入的 unit 和 append 参数)构建并返回对应的中文金额表示,如 “零元整”(默认参数情况)。
(4)整数部分转换逻辑
if (parseInt(integerNum, 10) > 0) {
let zeroCount = 0;
let IntLen = integerNum.length;
for (let i = 0; i < IntLen; i++) {
let n = integerNum[i];
let p = IntLen - i - 1;
let q = p / 4;
let m = p % 4;
if (n === "0") {
zeroCount++;
} else {
if (zeroCount > 0) {
chineseStr += cnNums[0];
}
// 归零
zeroCount = 0;
chineseStr += cnNums[parseInt(n)] + cnIntRadice[m];
}
if (m === 0 && zeroCount < 4) {
chineseStr += cnIntUnits[q];
}
}
chineseStr += unit;
}
- 当整数部分数字(通过
parseInt(integerNum, 10)判断)大于0时,进入一个循环来处理整数部分的每一位数字。 - 在循环中,对于每一位数字,先获取其对应的数字字符
n,并计算该位数字在整个整数金额中的位置信息,包括距离个位的位数p、所在的四位一组中的位置索引m以及对应的扩展单位层级q。 - 如果当前位数字是
0,则记录连续0的个数zeroCount,用于后续判断是否需要添加 “零” 字来正确表示中文金额的读法。当遇到非0数字时,如果之前有连续的0,则先在chineseStr中添加 “零” 字进行合理的中文表述衔接,并将zeroCount归零。然后根据当前数字和对应的基本单位cnIntRadice[m]构建出如 “叁佰” 这样的部分金额表述添加到chineseStr中。此外,当当前位处于每四位一组的个位位置(即m === 0)且连续0的个数小于4时,添加对应的扩展单位cnIntUnits[q]到chineseStr中,例如添加 “万”“亿” 等字。循环结束后,在chineseStr末尾添加unit(即整数金额对应的单位字符)。
(5)小数部分转换逻辑
if (decimalNum !== "") {
let decLen = decimalNum.length;
for (let i = 0; i < decLen; i++) {
let n = decimalNum[i];
if (n !== "0") {
chineseStr += cnNums[Number(n)] + cnDecUnits[i];
}
}
}
对于小数部分,如果 decimalNum 不为空字符串,说明存在小数金额需要转换。通过循环遍历小数部分的每一位数字,当数字不为 0 时,将对应的中文数字(通过 cnNums[Number(n)] 获取)和相应的小数单位(cnDecUnits[i])组合添加到 chineseStr 中,构建出小数金额的中文表示形式,比如将 0.34 中的 3 转换为 “叁角” 添加到字符串中。
(6)最终结果处理与返回
if (chineseStr === "") {
chineseStr += cnNums[0] + unit + append;
} else if (decimalNum === "") {
chineseStr += append;
}
return chineseStr;
最后,需要根据 chineseStr 的情况进行一些补充处理。如果 chineseStr 为空(可能是传入的金额为 0 且经过前面逻辑处理后为空字符串等情况),则按照设定的格式(使用 unit 和 append 参数)构建并返回对应的中文金额表示,如 “零元整”。如果小数部分 decimalNum 为空,表示金额是整数,就在 chineseStr 后面添加 append(默认是 “整” 字)。
(7)转换测试
1024
numberToChineseWords(1024) //壹仟零贰拾肆元整

99999999
numberToChineseWords(99999999) //玖仟玖佰玖拾玖万玖仟玖佰玖拾玖元整

12345.6789
numberToChineseWords(12345.6789) //壹万贰仟叁佰肆拾伍元陆角柒分捌毫玖厘

2、指令实现
export default {
bind: function (el, binding) {
const params = binding.value || {};
const { unit = "", append = "" } = params;
let originVal = el.innerText;
if (el.innerHTML) {
el.innerHTML = numberToChineseWords(el.innerText, unit, append);
}
el.addEventListener("focus", (event) => {
event.target.value = originVal;
});
el.addEventListener("blur", (event) => {
const value = event.target.value;
originVal = value;
event.target.value = numberToChineseWords(value, unit, append);
});
},
};
(1)参数解构与默认值设置
在 bind 函数中,首先通过 binding.value 获取指令绑定的值(通常是一个对象形式传递的参数),如果没有传递值,则默认为一个空对象,将其赋值给 params 变量。然后,从 params 对象中解构出 unit 和 append 参数,并分别设置了默认值为空字符串。这里的 unit 和 append 参数的含义与前面提到的 numberToChineseWords 函数中的对应参数一致,用于自定义中文大写金额中整数部分的单位以及整数金额后的追加字符。
(2)获取原始文本内容与初始转换
接着,获取元素的原始文本内容 originVal,这个值用于后续在元素获取焦点时还原用户看到的原始数字金额,方便编辑。如果元素有 innerHTML(即元素内部包含文本内容),则直接调用前面定义的 numberToChineseWords 函数,将元素的 innerText(也就是当前显示的文本内容,这里假设是数字金额相关)按照传入的 unit 和 append 参数进行转换,将转换后的中文大写金额结果重新赋值给元素的 innerHTML,实现了初始加载时将数字金额转换为中文大写金额显示的功能。
(3)焦点事件处理
添加 focus 事件监听器,当元素获得焦点时,在对应的事件处理函数中,将事件目标(也就是当前元素)的 value 属性设置为之前保存的 originVal,这样用户在点击输入框等操作使元素获得焦点时,能够看到原始的数字金额内容,便于进行修改编辑,保证了用户交互体验的连贯性和便捷性。
(4)失焦事件处理
添加 blur 事件监听器,当元素失去焦点时,在事件处理函数中,首先获取当前元素的 value 属性值(也就是用户编辑后的值),将其赋值给 originVal,以便后续再次操作时能基于最新的值进行还原等处理。然后,再次调用 numberToChineseWords 函数,将编辑后的 value 按照 unit 和 append 参数进行转换,将转换后的中文大写金额结果重新赋值给元素的 value 属性,实现了用户编辑完数字金额后,自动将其转换为中文大写金额进行显示的功能。
到此这篇关于vue指令实现数字和大写中文实时互转的文章就介绍到这了,更多相关vue数字和大写中文互转内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
