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;
相关推荐
碎碎念_4922 小时前
SpringBoot + Vue 前后端分离从 0 到 1 完整环境配置流程
vue.js·spring boot·后端
shuaijie05183 小时前
强制修改调用接口的api地址。
javascript·vue.js·ecmascript
JerrySir3 小时前
恶意 npm 包只活了 17 分钟:技术面试里,为什么“升级依赖”还不算止血?
javascript·安全
白帽小阳3 小时前
2026前端面试题!(附答案及解析)
javascript·网络·python·安全·web安全·网络安全·护网行动
这是个栗子3 小时前
前端开发中的常用工具函数(八)
开发语言·前端·javascript
Hilaku3 小时前
Vue 和 React 真正的差距,不在语法,而在团队犯错成本
前端·javascript·程序员
研☆香4 小时前
为什么变量声明在赋值前也能使用?—— 深入理解 JavaScript 变量提升与作用域
开发语言·前端·javascript
柯克七七4 小时前
我把 bug 修得太干净了,测试组以为这个模块本来就没问题
前端·javascript·typescript
Null1554 小时前
浏览器唤起桌面端应用(终极篇)
前端·javascript
妙码生花4 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(三十四):后台初始化请求实现
前端·javascript·go