input自定义指令,限制输入数字,字符串,数字,字母等规则

1. 安装和引入

首先,将这个自定义指令代码保存到一个文件,例如 v-input.js。然后在你的 Vue 项目中引入和注册这个自定义指令。

// main.js 或其他入口文件
import Vue from 'vue';
import VInput from './path/to/v-input';

Vue.directive('input', VInput);

2. 使用自定义指令

在你的 Vue 组件中,你可以使用这个自定义指令来控制输入框的行为。以下是如何在模板中使用这个指令的详细说明。

基本用法

你可以在模板中使用 v-input 指令来绑定各种输入限制类型。例如:

<template>
  <div>
    <!-- 只允许输入数字 -->
    <input v-input.num />

    <!-- 只允许输入浮点数 -->
    <input v-input.float="2" />

    <!-- 只允许输入正整数 -->
    <input v-input.intp />

    <!-- 只允许输入字母 -->
    <input v-input.alp />

    <!-- 只允许输入数字和字母 -->
    <input v-input.num_alp />

    <!-- 只允许输入四则运算符和数字 -->
    <input v-input.arith />

    <!-- 只允许输入在 10 到 100 范围内的整数 -->
    <input v-input.intRange="10-100" />

    <!-- 只允许输入双精度浮点数,在 1.0 到 100.0 范围内 -->
    <input v-input.double="1.0-100.0" />
  </div>
</template>
指令参数说明
  • num: 只允许输入数字。
  • num_point: 只允许输入数字和小数点。
  • float: 只允许输入浮点数。binding.value 可以指定小数点后的位数(例如 "2" 表示保留两位小数)。
  • int: 只允许输入整数(去掉开头的多个0)。
  • intp: 只允许输入正整数(去掉开头的0)。
  • alp: 只允许输入字母。
  • num_alp: 只允许输入数字和字母。
  • arith: 只允许输入算术运算符(+ - * /)和数字。
  • intRange: 只允许输入指定范围内的整数。例如 "10-100" 表示范围从 10 到 100。
  • double: 只允许输入指定范围内的双精度浮点数。例如 "1.0-100.0" 表示范围从 1.0 到 100.0。

3. 注意事项

  • 中文输入: 在使用中文输入法时,输入的处理可能会因为 compositionstartcompositionend 事件而被锁定。确保在输入完成后,能够正确更新绑定的数据。
  • 输入格式: 这个自定义指令处理了多种输入类型,确保你根据实际需求选择合适的指令参数。

4. 调试和测试

在使用自定义指令时,建议对不同类型的输入进行充分测试,以确保其行为符合预期。特别是针对边界条件和特殊字符的输入,进行详细的测试可以帮助确保输入验证的准确性。

完整示例

以下是一个完整的 Vue 组件示例,展示了如何使用自定义指令:

<template>
  <div>
    <h3>请输入不同类型的数据:</h3>
    <input v-input.num placeholder="数字" />
    <input v-input.float="2" placeholder="浮点数(2位小数)" />
    <input v-input.intp placeholder="正整数" />
    <input v-input.alp placeholder="字母" />
    <input v-input.num_alp placeholder="数字和字母" />
    <input v-input.arith placeholder="四则运算符和数字" />
    <input v-input.intRange="10-100" placeholder="范围内整数(10到100)" />
    <input v-input.double="1.0-100.0" placeholder="范围内浮点数(1.0到100.0)" />
  </div>
</template>

<script>
import VInput from './path/to/v-input';

export default {
  directives: {
    input: VInput
  }
};
</script>

<style>
/* 这里可以添加一些样式 */
</style>

5.具体指令代码

export default {
  bind(el, binding, vnode) {
    // 查找输入元素(支持 input 和 textarea)
    const input =
      el.querySelector(".el-input__inner") ||
      el.querySelector(".el-textarea__inner") ||
      el;

    // 处理中文输入法的 compositionstart 和 compositionend 事件
    input.addEventListener("compositionstart", () => {
      vnode.locking = true; // 锁定输入,避免中文输入导致双向绑定失效
    });
    input.addEventListener("compositionend", () => {
      vnode.locking = false; // 解除锁定
      input.dispatchEvent(new Event("input")); // 触发 input 事件,以更新数据
    });

    // 处理键盘输入事件
    input.onkeyup = () => {
      let newModifiers = vnode.key; // 获取指令参数(例如 'num' 或 'intp')
      let newRules;

      // 如果指令参数包含 ':'
      if (newModifiers && newModifiers.includes(":")) {
        let info = newModifiers.split(":");
        newModifiers = info[0]; // 指令类型(例如 'intRange')
        newRules = info[1]?.split("-"); // 规则(例如范围 [0-100])
      }

      if (vnode.locking) {
        return; // 如果输入被锁定,则不处理
      }

      // 根据指令参数选择不同的输入处理函数
      switch (newModifiers) {
        case "double":
          onlyDouble(input, newRules); // 处理双精度浮点数
          break;
        case "intRange":
          onlyIntRange(input, newRules); // 处理整数范围
          break;
        case "num":
          onlyNum(input); // 处理数字
          break;
        case "num_point":
          onlyNumPoint(input); // 处理数字和小数点
          break;
        case "float":
          onlyFloat(input, binding.value); // 处理浮点数(限制小数位数)
          break;
        case "int":
          onlyInt(input); // 处理整数(无前导零)
          break;
        case "intp":
          onlyIntp(input); // 处理正整数
          break;
        case "alp":
          onlyAlp(input); // 处理字母
          break;
        case "num_alp":
          onlyNumAlp(input); // 处理数字和字母
          break;
        case "arith":
          onlyArith(input); // 处理算术运算符和数字
          break;
        default:
          break;
      }

      input.dispatchEvent(new Event("input")); // 触发 input 事件,以更新数据
    };

    // 处理双精度浮点数输入
    function onlyDouble(input, rules) {
      onlyFloat(input, 1); // 先确保输入符合浮点数格式
      if (input.value < Number(rules[0])) {
        input.value = Number(rules[0]); // 处理范围下限
      } else if (input.value > Number(rules[1])) {
        input.value = Number(rules[1]); // 处理范围上限
      }
    }

    // 处理整数范围输入
    function onlyIntRange(input, rules) {
      onlyIntp(input); // 处理正整数输入
      if (input.value < Number(rules[0])) {
        input.value = Number(rules[0]); // 处理范围下限
      } else if (input.value > Number(rules[1])) {
        input.value = Number(rules[1]); // 处理范围上限
      }
    }

    // 处理仅数字输入
    function onlyNum(input) {
      input.value = input.value.replace(/\D+/g, ""); // 去掉非数字字符
    }

    // 处理整数输入(无前导零)
    function onlyInt(input) {
      let value = input.value.replace(/\D+/g, ""); // 去掉非数字字符
      input.value = value ? Number(value).toString() : value; // 去掉开头多个0
    }

    // 处理正整数输入(去掉前导零)
    function onlyIntp(input) {
      const value = input.value.replace(/\D+/g, ""); // 去掉非数字字符
      input.value = /^[1-9][0-9]*$/.test(value) ? value : value.replace(/^0+/, ""); // 确保为正整数,去掉前导零
    }

    // 处理数字和小数点输入
    function onlyNumPoint(input) {
      input.value = input.value.replace(/[^\d.]/g, ""); // 允许数字和小数点
    }

    // 处理浮点数输入(限制小数位数)
    function onlyFloat(input, n) {
      let value = input.value;
      value = value.replace(/[^\d.]/g, ""); // 允许数字和小数点
      value = value.replace(/^\./g, ""); // 去掉开头的点
      value = value.replace(".", "$#$").replace(/\./g, "").replace("$#$", "."); // 处理多个点的情况
      if (n && Number(n) > 0) {
        const d = new Array(Number(n)).fill("\\d").join(""); // 构建正则表达式
        const reg = new RegExp(`^(\\-)*(\\d+)\\.(${d}).*$`, "ig");
        value = value.replace(reg, "$1$2.$3"); // 限制小数位数
      }
      if (value && !value.includes(".")) {
        value = Number(value).toString(); // 去掉开头多个0
      }
      input.value = value;
    }

    // 处理字母输入
    function onlyAlp(input) {
      input.value = input.value.replace(/[^A-Za-z]/g, ""); // 只允许字母
    }

    // 处理数字和字母输入
    function onlyNumAlp(input) {
      input.value = input.value.replace(/[^A-Za-z0-9]/g, ""); // 只允许数字和字母
    }

    // 处理算术运算符和数字输入
    function onlyArith(input) {
      let value = input.value;
      if (value) {
        input.value = value.split("").reduce((prev, cur) => {
          if (/^[\d|\-|\+|\*|\/|\.|\(|\)]+$/.test(cur)) {
            return prev + cur; // 只允许数字和算术运算符
          }
          return prev;
        }, "");
      }
    }
  },
};

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农六六

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值