0
点赞
收藏
分享

微信扫一扫

vue 关于输入框的一些指令

禾木瞎写 2024-09-19 阅读 31

/**
 * 指令 - 限制输入框
 */
import Vue from 'vue'
import {
  Message
} from 'element-ui'

/**
 * 输入保留两位小数
 * data-multiple: 整倍数
 * data-minus: 可输入负数
 * max:最大值
 * min:最小值
 */
Vue.directive('inputFloat', {
  bind (el, binding, vnode) {
    const input = el.getElementsByTagName('input')[0]
    input.addEventListener('compositionstart', function () {
      vnode.inputLocking = true
    })
    input.addEventListener('compositionend', function () {
      vnode.inputLocking = false
      input.dispatchEvent(new Event('input'))
    })
    input.addEventListener('input', function () {
      if (vnode.inputLocking) return
      const oldValue = input.value
      let newValue = input.value
      let reg
      if (input.dataset.minus) {
        reg = /[^-\d.]/g // 可以输入负数
      } else {
        reg = /[^\d.]/g
      }
      newValue = newValue.replace(reg, '')
      newValue = newValue.replace(/[^-\d.]/g, '')
      newValue = newValue.replace(/^\./g, '')
      newValue = newValue.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.')
      newValue = newValue.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3')
      if (newValue && newValue != '-') {
        const arr = newValue.split('.')
        newValue = Number(arr[0]) + (arr[1] === undefined ? '' : '.' + arr[1]) // 去掉开头多余的0
      }
      // 判断是否需要更新,避免进入死循环
      if (newValue !== oldValue) {
        input.value = newValue
        input.dispatchEvent(new Event('input')) // 通知v-model更新
      }
    })
    // input 事件无法处理小数点后面全是零的情况 因为无法确定用户输入的0是否真的应该清除,如3.02。放在blur中去处理
    input.addEventListener('blur', function () {
      const oldValue = input.value
      let newValue = input.value
      let numValue = Number(newValue)
      const maxVal = Number(input.max || undefined)
      const minVal = Number(input.min || undefined)
      const multiple = Number(input.dataset.multiple || undefined)

      // 含有整倍数
      if (newValue && !isNaN(multiple) && (numValue % multiple !== 0)) {
        newValue = ''
        Message && Message(`限制输入:请输入${multiple}的整倍数!`)
      }
      // 允许设定的最大值
      if (newValue && !isNaN(maxVal) && numValue > maxVal) {
        numValue = maxVal
      }
      // 允许设定的最小值
      if (newValue && !isNaN(minVal) && numValue < minVal) {
        numValue = minVal
      }
      // 负数情况
      if (newValue == '-') newValue = ''
      if (newValue == '-0') newValue = '0'

      if (newValue) {
        newValue = numValue.toFixed(2)
      }

      // 判断是否需要更新,避免进入死循环
      if (newValue !== oldValue) {
        input.value = newValue
        input.dispatchEvent(new Event('input')) // 通知v-model更新
      }
    })
  }
})

/**
 * 输入整数
 * data-multiple: 整倍数
 * data-minus: 可输入负数
 * max:最大值
 * min:最小值
 */
Vue.directive('inputInt', {
  bind (el, binding, vnode) {
    const input = el.getElementsByTagName('input')[0]
    input.addEventListener('compositionstart', function () {
      vnode.inputLocking = true
    })
    input.addEventListener('compositionend', function () {
      vnode.inputLocking = false
      input.dispatchEvent(new Event('input'))
    })
    input.addEventListener('input', function () {
      if (vnode.inputLocking) return
      const oldValue = input.value
      let newValue = input.value
      let reg
      if (input.dataset.minus) {
        reg = /^0+(\d)|[^-\d]+/g // 可以输入负数
      } else {
        reg = /^0+(\d)|[^\d]+/g
      }
      newValue = newValue.replace(reg, '')

      if (newValue && newValue != '-') {
        newValue = '' + Number(newValue) // 去掉开头多余的0
      }

      // 判断是否需要更新,避免进入死循环
      if (newValue !== oldValue) {
        input.value = newValue
        input.dispatchEvent(new Event('input')) // 通知v-model更新
      }
    })
    input.addEventListener('blur', function () {
      const oldValue = input.value
      let newValue = input.value
      const numValue = Number(newValue)
      const maxVal = Number(input.max || undefined)
      const minVal = Number(input.min || undefined)
      const multiple = Number(input.dataset.multiple || undefined)

      // 含有整倍数
      if (newValue && !isNaN(multiple) && (numValue % multiple !== 0)) {
        newValue = ''
        Message && Message(`限制输入:请输入${multiple}的整倍数!`)
      }
      // 允许设定的最大值
      if (newValue && !isNaN(maxVal) && numValue > maxVal) {
        newValue = '' + maxVal
      }
      // 允许设定的最小值
      if (newValue && !isNaN(minVal) && numValue < minVal) {
        newValue = '' + minVal
      }
      // 负数情况
      if (newValue == '-') newValue = ''
      if (newValue == '-0') newValue = '0'

      // 判断是否需要更新,避免进入死循环
      if (newValue !== oldValue) {
        input.value = newValue
        input.dispatchEvent(new Event('input')) // 通知v-model更新
      }
    })
  }
})

/**
 * 只能输入字符和数字,排除中文和符号
 */
Vue.directive('inputNE', {
  bind (el, binding, vnode) {
    const input = el.getElementsByTagName('input')[0]
    input.addEventListener('compositionstart', function () {
      vnode.inputLocking = true
    })
    input.addEventListener('compositionend', function () {
      vnode.inputLocking = false
      input.dispatchEvent(new Event('input'))
    })
    input.addEventListener('input', function () {
      if (vnode.inputLocking) return
      const oldValue = input.value
      let newValue = input.value
      newValue = newValue.replaceAll(
        /[\u4e00-\u9fa5/\s+/]|[`~!@#$%^&*() \+ =<>?"{}|., \/ ;' \\ [ \] ·~!@#¥%……&*()—— \+ ={}|《》?:“”【】、;‘’,。、]/g,
        '')

      // 判断是否需要更新,避免进入死循环
      if (newValue !== oldValue) {
        input.value = newValue
        input.dispatchEvent(new Event('input')) // 通知v-model更新
      }
    })
  }
})
/**
 * 限制输入特定字符
 */
let restrictReg = new RegExp("'", 'g') //特定字符正则
Vue.directive('restrict', {
  bind (el, binding, vnode) {
    let input = ['input', 'textarea'].includes(el.tagName.toLowerCase()) ? el : (el.querySelector('input') || el.querySelector('textarea'))
    input.addEventListener('compositionstart', function () {
      vnode.inputLocking = true
    })
    input.addEventListener('compositionend', function () {
      vnode.inputLocking = false
      input.dispatchEvent(new Event('input'))
    })
    input.addEventListener('input', () => {
      if (vnode.inputLocking) return
      const oldValue = input.value
      let newValue = oldValue.replace(restrictReg, '');
      // 判断是否需要更新,避免进入死循环
      if (newValue !== oldValue) {
        input.value = newValue
        input.dispatchEvent(new Event('input')) // 通知v-model更新
      }
    });
  }
});

举报

相关推荐

0 条评论