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;
相关推荐
前端小白在前进25 分钟前
力扣刷题:千位分割数
javascript·算法·leetcode
Hilaku29 分钟前
那个把代码写得亲妈都不认的同事,最后被劝退了🤷‍♂️
前端·javascript·代码规范
Dragon Wu31 分钟前
TanStack Query(React Query) 常用api及操作总结
前端·javascript·前端框架
喵个咪43 分钟前
开箱即用的 GoWind Admin|风行,企业级前后端一体中后台框架:用 JavaScript/Lua 解锁动态业务扩展能力
javascript·go·lua
BD_Marathon1 小时前
Vue3_插值表达式
javascript
梦想是准点下班1 小时前
【vue3】 + 【vite】 + 【vite-plugin-obfuscator】混淆打包 => 放弃了,样式会丢
前端·vue.js
前端达人1 小时前
原生JavaScript vs 前端框架,2026年该怎么选?
开发语言·前端·javascript·前端框架·ecmascript
梦想是准点下班1 小时前
【vue3】 + 【vite】 + 【rollup-plugin-obfuscator】混淆打包 => 打包报错
前端·vue.js
星_离1 小时前
高德地图-物流路线
前端·vue.js
AAA阿giao1 小时前
JavaScript 中 this 的终极解析:从 call、bind 到箭头函数的深度探索
前端·javascript·ecmascript 6