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;
相关推荐
Moment6 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
爱敲代码的小鱼6 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
吹牛不交税7 小时前
admin.net-v2 框架使用笔记-netcore8.0/10.0版
vue.js·.netcore
MZ_ZXD0018 小时前
springboot旅游信息管理系统-计算机毕业设计源码21675
java·c++·vue.js·spring boot·python·django·php
铅笔侠_小龙虾8 小时前
Flutter 实战: 计算器
开发语言·javascript·flutter
大模型玩家七七9 小时前
梯度累积真的省显存吗?它换走的是什么成本
java·javascript·数据库·人工智能·深度学习
2501_944711439 小时前
JS 对象遍历全解析
开发语言·前端·javascript
发现一只大呆瓜10 小时前
虚拟列表:支持“向上加载”的历史消息(Vue 3 & React 双版本)
前端·javascript·面试
阔皮大师10 小时前
INote轻量文本编辑器
java·javascript·python·c#
lbb 小魔仙10 小时前
【HarmonyOS实战】React Native 表单实战:自定义 useReactHookForm 高性能验证
javascript·react native·react.js