input输入框输入数字之后展示千分位(财务系统专用)

财务专用数字

  • 财务系统的数字展示千分位,保留两位小数是必须的要求,
  • 比如:55555.66 一定要展示位 55,555.66,方便财务人员数位数
  • 比如:123456789.55666 展示为123,456,789.56,方便税局入库等

显示数字的js

js 复制代码
moneyFormat(num) {
    if (isFinite(num)) { // num是数字
        return Number(num).toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
    }
},

input框输入的时候展示的js(vue指令)

js 复制代码
const installDirectives = (app) => {
  function focus(e) {
    // 从元素上获取原始值
    const originalValue = e.target.dataset.originalValue;
    // 移除千分位分隔符
    e.target.value = originalValue || e.target.value.replace(/,/g, "");
  }

  function input(e) {
    let value = e.target.value.trim();
    // 验证是否是合法的数字格式(只允许数字和小数点)
    if (!/^[0-9.]*$/.test(value)) {
      // 移除非法字符
      value = value.replace(/[^0-9.]/g, "");
      e.target.value = value;
      return;
    }

    // 确保只有一个小数点
    if ((value.match(/\./g) || []).length > 1) {
      value = value.replace(/(\..*)\./g, "$1");
      e.target.value = value;
      return;
    }

    // 如果输入合法,保存原始值
    e.target.dataset.originalValue = value;
  }

  function blur(e) {
    let value = e.target.value.trim();
    if (value === "") {
      e.target.value = "";
      return;
    }

    // 将值转换为数字并四舍五入到两位小数
    const num = parseFloat(value);
    if (!isNaN(num)) {
      // 四舍五入到两位小数
      const roundedNum = Math.round(num * 100) / 100;

      // 转换为字符串并分割整数和小数部分
      const roundedStr = roundedNum.toString();
      const parts = roundedStr.split(".");
      let integerPart = parts[0];
      let decimalPart = parts.length > 1 ? parts[1] : "";

      // 确保小数点后两位
      if (decimalPart.length === 1) {
        decimalPart += "0";
      } else if (decimalPart.length === 0) {
        decimalPart = "00";
      }

      // 添加千分位分隔符
      integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");

      // 格式化后的值
      e.target.value = `${integerPart}.${decimalPart}`;
      e.target.dataset.originalValue = roundedNum.toFixed(2);
    } else {
      // 如果转换失败,恢复原始值
      e.target.value = e.target.dataset.originalValue || "";
    }
  }

  app.directive("two-decimal", {
    beforeMount(el) {
      const inputEl = el.querySelector("input");

      // 初始化原始值
      if (inputEl.value) {
        const num = parseFloat(inputEl.value.replace(/,/g, ""));
        if (!isNaN(num)) {
          inputEl.dataset.originalValue = inputEl.value.replace(/,/g, "");
        }
      }

      // 添加事件监听器
      inputEl.addEventListener("focus", focus);
      inputEl.addEventListener("input", input);
      inputEl.addEventListener("blur", blur);
      inputEl.addEventListener("paste", (e) => {
        // 验证粘贴的内容
        const pastedData = (e.clipboardData || window.clipboardData).getData("text");
        if (!/^[0-9.]*$/.test(pastedData)) {
          e.preventDefault();
        }
      });
    },
    beforeUnmount(el) {
      const inputEl = el.querySelector("input");
      inputEl.removeEventListener("focus", focus);
      inputEl.removeEventListener("input", input);
      inputEl.removeEventListener("blur", blur);
      inputEl.removeEventListener("paste", (e) => {
        const pastedData = (e.clipboardData || window.clipboardData).getData("text");
        if (!/^[0-9.]*$/.test(pastedData)) {
          e.preventDefault();
        }
      });
    },
  });
};

export default installDirectives;
相关推荐
quan26319 分钟前
Vue实践篇-02,AI生成代码
前端·javascript·vue.js
qb1 小时前
vue3.5.18源码-编译-入口
前端·vue.js·架构
小桥风满袖1 小时前
极简三分钟ES6 - 类与继承
前端·javascript
虫无涯1 小时前
【分享】基于百度脑图,并使用Vue二次开发的用例脑图编辑器组件
前端·vue.js·编辑器
子兮曰1 小时前
🚀99% 的前端把 reduce 用成了「高级 for 循环」—— 这 20 个骚操作让你一次看懂真正的「函数式折叠」
前端·javascript·typescript
wifi歪f1 小时前
📦 qiankun微前端接入实战
前端·javascript·面试
小桥风满袖1 小时前
极简三分钟ES6 - Symbol
前端·javascript
子兮曰1 小时前
🚀Map的20个神操作,90%的开发者浪费了它的潜力!最后的致命缺陷让你少熬3天夜!
前端·javascript·ecmascript 6
NewChapter °1 小时前
如何通过 Gitee API 上传文件到指定仓库
前端·vue.js·gitee·uni-app
练习时长两年半的Java练习生(升级中)1 小时前
从0开始学习Java+AI知识点总结-30.前端web开发(JS+Vue+Ajax)
前端·javascript·vue.js·学习·web