当前位置: 首页 > news >正文

vue2自定义指令实现 el-input 输入数字,小数点两位 最高10位,不满足则截取符合规则的值作为新值

步骤 1:创建自定义指令

// 处理输入值,确保符合规则
function processValue(value) {
  // 过滤非数字和小数点
  let filtered = value.replace(/[^\d.]/g, '');
  const firstDotIndex = filtered.indexOf('.');
  
  // 处理多个小数点,保留第一个
  if (firstDotIndex !== -1) {
    filtered = filtered.substring(0, firstDotIndex + 1) + filtered.substring(firstDotIndex + 1).replace(/\./g, '');
  }
  
  // 分割整数和小数部分
  const parts = filtered.split('.');
  let integerPart = (parts[0] || '').slice(0, 10); // 整数最多10位
  let decimalPart = parts.length > 1 ? parts[1].slice(0, 2) : ''; // 小数最多两位
  
  // 处理以小数点开头的情况(如 ".98" → "0.98")
  if (filtered.startsWith('.') && integerPart === '') {
    integerPart = '0';
  }
  
  // 组合结果
  let newValue = integerPart;
  if (parts.length > 1 || filtered.endsWith('.')) {
    newValue += '.' + decimalPart;
  }
  
  return newValue;
}

// 注册自定义指令
Vue.directive('number', {
  bind(el, binding, vnode) {
    const input = el.querySelector('input.el-input__inner');
    if (!input) return;
    
    let composing = false; // 标记是否在输入法组合中
    
    const handler = (e) => {
      if (composing) return;
      const newVal = processValue(e.target.value);
      if (e.target.value !== newVal) {
        e.target.value = newVal;
        input.dispatchEvent(new Event('input', { bubbles: true })); // 触发更新
      }
    };
    
    // 输入法处理
    const compositionStart = () => { composing = true; };
    const compositionEnd = (e) => {
      composing = false;
      handler(e);
    };
    
    input.addEventListener('compositionstart', compositionStart);
    input.addEventListener('compositionend', compositionEnd);
    input.addEventListener('input', handler);
    
    // 保存处理函数以便解绑
    el._numberHandlers = { compositionStart, compositionEnd, handler };
    
    // 初始值处理
    const initialValue = vnode.componentInstance?.value ?? input.value;
    const processedVal = processValue(initialValue);
    if (initialValue !== processedVal) {
      vnode.componentInstance?.$emit('input', processedVal);
    }
  },
  
  update(el, binding, vnode) {
    const input = el.querySelector('input.el-input__inner');
    const currentValue = vnode.componentInstance?.value ?? input?.value;
    if (currentValue === undefined) return;
    
    const newVal = processValue(currentValue);
    if (currentValue !== newVal) {
      vnode.componentInstance?.$emit('input', newVal);
    }
  },
  
  unbind(el) {
    const input = el.querySelector('input.el-input__inner');
    if (input && el._numberHandlers) {
      const { compositionStart, compositionEnd, handler } = el._numberHandlers;
      input.removeEventListener('compositionstart', compositionStart);
      input.removeEventListener('compositionend', compositionEnd);
      input.removeEventListener('input', handler);
      delete el._numberHandlers;
    }
  }
});

步骤 2:在组件中使用指令

<template>
  <el-input v-number v-model="inputValue"></el-input>
</template>

<script>
export default {
  data() {
    return {
      inputValue: ''
    };
  }
};
</script>

功能说明

  1. 过滤非数字字符:只允许输入数字和小数点。
  2. 限制小数点数量:确保只保留第一个小数点,后续的自动移除。
  3. 整数部分限制:最多输入 10 位整数,超长部分截断。
  4. 小数部分限制:最多输入 2 位小数,超长部分截断。
  5. 输入法兼容:处理中文输入法状态,避免中途过滤。
  6. 初始值处理:当初始值不符合规则时自动修正。
  7. 实时更新:通过触发 input 事件确保 v-model 同步更新。

注意事项

  • 该指令依赖于 Element UI 的 el-input 结构,确保内部输入框的类名为 el-input__inner
  • 处理后的值会覆盖用户输入,确保始终符合规则。
  • 支持输入法组合输入(如中文拼音),提升用户体验。

相关文章:

  • 【Pytorch实战教程】拆解PyTorch中的多头注意力:原来Transformer的核心组件可以这样玩
  • 关于WPS的Excel点击单元格打开别的文档的两种方法的探究【为单元格添加超链接】
  • 【VS小知识】VS如何保存UTF8
  • Flutter Dart 面向对象编程全面解析
  • Day 2:基础知识巩固(HTML、CSS、JavaScript)
  • matlab 自适应模糊PID在反应釜温度控制中的应用
  • vue2用vscode调试打不上断点
  • Select 选择器选项位置偏移的解决方案
  • 出海行动派 | 全球服务新征程!Bonree ONE海外版正式发布
  • 使用 PaddlePaddle 官方提供的 Docker 镜像
  • Python个人学习笔记(15):模块(time,datetime,random)
  • ubuntu中使用ollama部署本地deepseek
  • 在Spring Boot项目中接入DeepSeek深度求索,感觉笨笨的呢
  • SpringMVC(五)拦截器
  • 深度学习中LayerNorm与RMSNorm对比
  • Web安全:保护您的网站免受网络威胁
  • 2024下半年真题 系统架构设计师 案例分析
  • 将景区天气数据存储到Excel文件中
  • 【微服务】Nacos 配置动态刷新(简易版)(附配置)
  • 基于express+TS+mysql+sequelize的后端开发环境搭建
  • 中欧金融工作组第二次会议在比利时布鲁塞尔举行
  • 《歌手2025》公布首发阵容,第一期就要淘汰一人
  • 马上评丨火车穿村而过多人被撞身亡,亡羊补牢慢不得
  • 演员黄晓明、金世佳进入上海戏剧学院2025年博士研究生复试名单
  • 从这些电影与影像,看到包容开放的上海
  • 专访|韩国世宗研究所中国研究中心主任:李在明若上台将推行均衡外交