vue怎么使用directive限制表单输入整数、小数

寻技术 Html/CSS / VUE 2023年09月11日 61

这篇文章主要介绍“vue怎么使用directive限制表单输入整数、小数”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vue怎么使用directive限制表单输入整数、小数”文章能帮助大家解决问题。

限制小数时可以输入整数

1.第一种方法:

const limitPositive = Vue.directive('limitPositive', {
  update(el, {value = 0}, vnode) {  // 当被绑定的元素插入到 DOM 中时
    let iscancel = false;
    let num = value
    const inputEvent = e => {
      if (iscancel) {
        return false;
      }
      let res = '/^d*(.?d{0,'+num+'})/g'
      if (num) {
        e.target.value = (e.target.value.match(eval('(' + res + ')'))[0]) || null
      }else {
        e.target.value = (e.target.value.match(/^d*/g)[0]) || null
      }

      let v = e.target.value;//为绑定的值
      vnode.data.model.callback(v);//改变虚拟节点上v-model的值
    };
    el.oninput = inputEvent;
    //解决输入中文的问题
    el.addEventListener("compositionstart", e => {
      iscancel = true;
    });
    el.addEventListener("compositionend", e => {
      iscancel = false;
      inputEvent(e);
    });
  }
})
export { limitPositive }

使用方法

import limitPositive from '@/utils/directives.js'
v-limitPositive="1" //一位小数,数字可以改变
v-limitPositive 整数

2.第二种方法:

先建立一个num.js文件

/**
 * 设置输入框的值,触发input事件,改变v-model绑定的值
 * */
const setVal = (val, el, vNode) => {
  if (vNode.componentInstance) {
    // 如果是自定义组件就触发自定义组件的input事件
    vNode.componentInstance.$emit('input', val)
  } else {
    // 如果是原生组件就触发原生组件的input事件
    el.value = val
    el.dispatchEvent(new Event('input'))
  }
}

/**
* 参数检查
* */
const optionCheck = (binding) => {
  // 范围值是否为数值
  if ((binding.value.max && typeof binding.value.max !== 'number') || (binding.value.min && typeof binding.value.min !== 'number')) {
    throw new Error('范围参数必须是数字')
  }
  // 最大最小值存在的时候判断最大值与最小值是否相等
  if (binding.value.max === binding.value.min && typeof binding.value.max !== 'undefined' && typeof binding.value.min !== 'undefined') {
    throw new Error('最大值和最小值不能相等')
  }
}

/**
* 判断是否为无效值
* */
const isInvalidVal = (bindValue) => {
  return bindValue === null || isNaN(Number(bindValue)) || bindValue.toString().indexOf('.') === bindValue.length - 1 || bindValue.toString().indexOf('e') !== -1
}

/**
* 处理数值范围,如果输入值超过最大值或最小值,将会被自动设置为边界值
* */
const dealRange = (inputValue, binding) => {
  const bindMax = typeof binding.value.max === 'undefined' ? Infinity : binding.value.max
  const bindMin = typeof binding.value.min === 'undefined' ? -Infinity : binding.value.min
  let result = inputValue
  if (inputValue < bindMin) {
    result = bindMin
  }
  if (inputValue > bindMax) {
    result = bindMax
  }
  return result
}

/**
* 阻止输入
* */
const preventInput = (event) => {
  if (event.preventDefault) {
    event.preventDefault()
  } else {
    event.returnValue = false
  }
}
export default {
  bind(el, binding, vNode) {
    optionCheck(binding)
    // 处理无效值
    const bindValue = vNode.data.model.value
    if (isInvalidVal(bindValue)) {
      setVal(null, el, vNode)
      return
    }

    // 处理数值范围
    const inputVal = dealRange(bindValue, binding)
    setVal(inputVal, el, vNode)
  },
  inserted(el, binding, vNode) {
    let content
    // 按键按下=>只允许按照一定规则输入 数字/小数点/减号
    el.addEventListener('keypress', e => {
      const inputKey = String.fromCharCode(typeof e.charCode === 'number' ? e.charCode : e.keyCode)
      const inputReg = /d|.|-/
      content = e.target.value
      /**
           * 1.输入值不是数字、小数点、减号
           * 2.输入框为空或只有减号,不能输入小数点
           * 3.重复输入小数点
           * 4.输入框已有值,不能输入减号
           * 5.重复输入减号
           */
      // todo:已有值的时候,选中输入框的所有值输入减号‘-',无法覆盖输入
      if (!inputReg.test(inputKey)) {
        preventInput(e)
      } else if (((content === '' || content === '-') && inputKey === '.')) {
        preventInput(e)
      } else if ((content.indexOf('.') !== -1 && inputKey === '.')) {
        preventInput(e)
      } else if ((content !== '' && inputKey === '-')) {
        preventInput(e)
      } else if ((content.indexOf('-') !== -1 && inputKey === '-')) {
        preventInput(e)
      }
    })
    // 按键弹起=>并限制最大最小
    el.addEventListener('keyup', e => {
      if (e.keyCode === 8) {
        return
      }
      // 处理无效值
      const bindValue = e.target.value
      if (bindValue === null) {
        setVal(null, el, vNode)
        return
      }

      // 处理数值范围
      const inputVal = dealRange(bindValue, binding)
      setVal(inputVal, el, vNode)
    })
    // 失去焦点=>保留指定位小数
    el.addEventListener('focusout', e => { // 此处会在 el-input 的 @change 后执行
      // 处理无效值
      const bindValue = e.target.value
      if (isInvalidVal(bindValue)) {
        setVal(null, el, vNode)
        return
      }

      content = parseFloat(e.target.value)
      const contentStr = String(content)
      if (contentStr.indexOf('.') >= 0 && contentStr.split('.')[1].length > binding.value.precision) {
        let arg_precision = 0// 默认保留至整数
        if (binding.value.precision) {
          arg_precision = parseFloat(binding.value.precision)
        }
        content = content.toFixed(arg_precision)
      }
      setVal(content, el, vNode)
    })
  }
}

在index.js文件引入

import onlyNumber from './num'
const install = Vue => {
  Vue.directive('onlyNumber', onlyNumber)
}
/*
  Vue.use( plugin )
  安装 Vue.js 插件。如果插件是一个对象,必须提供 install 方法。
  如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入。
  该方法需要在调用 new Vue() 之前被调用。
  当 install 方法被同一个插件多次调用,插件将只会被安装一次。
*/

if (window.Vue) {
  window['onlyNumber'] = onlyNumber
  Vue.use(install); // eslint-disable-line
}

onlyNumber.install = install
export default onlyNumber

// 使用  例子:v-only-number="{max:100,min:0,precision:2}"

使用例子:
// 在main.js全局注入
import onlyNumber from &lsquo;@/directive/num&rsquo;
Vue.use(onlyNumber)

v-only-number=“{max:100,min:0,precision:2}”
max:最大值
min:最小值
precision:保留小数

<el-input v-model="value" v-only-number="{max:1000,min:0}" placeholder="请输入"/>
关闭

用微信“扫一扫”