vue指令实现数字和大写中文实时互转

 更新时间:2024年12月11日 08:32:17   作者:JYeontu  
这篇文章主要介绍了如何使用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 且经过前面逻辑处理后为空字符串等情况),则按照设定的格式(使用 unitappend 参数)构建并返回对应的中文金额表示,如 “零元整”。如果小数部分 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 对象中解构出 unitappend 参数,并分别设置了默认值为空字符串。这里的 unitappend 参数的含义与前面提到的 numberToChineseWords 函数中的对应参数一致,用于自定义中文大写金额中整数部分的单位以及整数金额后的追加字符

(2)获取原始文本内容与初始转换

接着,获取元素的原始文本内容 originVal,这个值用于后续在元素获取焦点时还原用户看到的原始数字金额,方便编辑。如果元素有 innerHTML(即元素内部包含文本内容),则直接调用前面定义的 numberToChineseWords 函数,将元素的 innerText(也就是当前显示的文本内容,这里假设是数字金额相关)按照传入的 unitappend 参数进行转换,将转换后的中文大写金额结果重新赋值给元素的 innerHTML,实现了初始加载时将数字金额转换为中文大写金额显示的功能。

(3)焦点事件处理

添加 focus 事件监听器,当元素获得焦点时,在对应的事件处理函数中,将事件目标(也就是当前元素)的 value 属性设置为之前保存的 originVal这样用户在点击输入框等操作使元素获得焦点时,能够看到原始的数字金额内容,便于进行修改编辑,保证了用户交互体验的连贯性和便捷性。

(4)失焦事件处理

添加 blur 事件监听器,当元素失去焦点时,在事件处理函数中,首先获取当前元素的 value 属性值(也就是用户编辑后的值),将其赋值给 originVal,以便后续再次操作时能基于最新的值进行还原等处理。然后,再次调用 numberToChineseWords 函数,将编辑后的 value 按照 unitappend 参数进行转换,将转换后的中文大写金额结果重新赋值给元素的 value 属性,实现了用户编辑完数字金额后,自动将其转换为中文大写金额进行显示的功能。

到此这篇关于vue指令实现数字和大写中文实时互转的文章就介绍到这了,更多相关vue数字和大写中文互转内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解Vue基于 Nuxt.js 实现服务端渲染(SSR)

    详解Vue基于 Nuxt.js 实现服务端渲染(SSR)

    直接使用 Vue 构建前端单页面应用,页面源码时只有简单的几行 html,这并不利于网站的 SEO,这时候就需要服务端渲染,本篇文章主要介绍了详解Vue基于 Nuxt.js 实现服务端渲染(SSR),具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-04-04
  • vue 基于abstract 路由模式 实现页面内嵌的示例代码

    vue 基于abstract 路由模式 实现页面内嵌的示例代码

    这篇文章主要介绍了vue 基于abstract 路由模式 实现页面内嵌的示例代码,帮助大家更好的理解和使用vue框架,感兴趣的朋友可以了解下
    2020-12-12
  • 基于vue-cli vue-router搭建底部导航栏移动前端项目

    基于vue-cli vue-router搭建底部导航栏移动前端项目

    这篇文章主要介绍了基于vue-cli vue-router搭建底部导航栏移动前端项目,项目中主要用了Flex布局,以及viewport相关知识,已达到适应各终端屏幕的目的。需要的朋友可以参考下
    2018-02-02
  • vue项目如何配置public静态资源路径访问

    vue项目如何配置public静态资源路径访问

    这篇文章主要介绍了vue项目如何配置public静态资源路径访问方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • vue表单自定义校验规则介绍

    vue表单自定义校验规则介绍

    今天小编就为大家分享一篇vue表单自定义校验规则介绍,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-08-08
  • 微信小程序Echarts动态使用及图表层级踩坑解决方案

    微信小程序Echarts动态使用及图表层级踩坑解决方案

    这篇文章主要为大家介绍了微信小程序Echarts动态使用及图表层级踩坑解决方案,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • Vue实现高德坐标转GPS坐标功能的示例详解

    Vue实现高德坐标转GPS坐标功能的示例详解

    生活中常用的几种坐标有:WGS-84、GCJ-02与BD-09。本文将利用Vue实现高德坐标转GPS坐标功能,即实现GCJ-02坐标转换成WGS-84坐标,需要的可以参考一下
    2022-04-04
  • Vue 解决多级动态面包屑导航的问题

    Vue 解决多级动态面包屑导航的问题

    今天小编就为大家分享一篇Vue 解决多级动态面包屑导航的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • vue+element-ui前端使用print-js实现打印功能(可自定义样式)

    vue+element-ui前端使用print-js实现打印功能(可自定义样式)

    Print.js主要是为了帮助我们直接在浏览器中开发打印功能,下面这篇文章主要给大家介绍了关于vue+element-ui前端使用print-js实现打印功能(可自定义样式)的相关资料,需要的朋友可以参考下
    2022-11-11
  • Vue3中进行点击事件埋点

    Vue3中进行点击事件埋点

    本文主要介绍了Vue3中进行点击事件埋点,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-01-01

最新评论