本文介绍如何在Vue中封装一个通用指令,实现用户输入数字失焦后实时转换为大写中文,聚焦时还原为数字以便编辑。通过解析数字转中文逻辑及指令绑定细节,提供完整的代码实现与测试用例,帮助开发者快速集成该功能。
前言
近期开发中遇到一个需求:用户输入数字并失去焦点时,需实时将数字转换为大写中文;当重新聚焦时,则需将大写中文还原为数字,以便用户继续修改。为此,我们可以封装一个通用的Vue指令来实现这一转换功能。接下来,我们将详细探讨如何实现该指令。
效果演示

访问链接
访问地址: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数字和大写中文互转内容,请搜索本站以前的文章或继续浏览相关文章。希望大家以后多多支持本站!