正则使用正则表达式:

可以输入数字和小数点后有两位以内的小数: /^(([^0][0-9]+|0)\.([0-9]{1,2})$)|^([^0][0-9]+|0)$/

只能输入非零开头的纯数字: /^([^0][0-9]+|0)$/

只能输入带小数点的小数: /^(([^0][0-9]+|0)\.([0-9]{1,2}))$/

Vue 指令:

directives: {
  // 限制只能输入整数
  inputInt: {
    bind(el, binding, vnode) {
      let input = vnode.elm;
      input.addEventListener('compositionstart', () => {
        vnode.inputLocking = true
      })
      input.addEventListener('compositionend', () => {
        vnode.inputLocking = false
        input.dispatchEvent(new Event('input'))
      })
      input.addEventListener('input', () => {
        if(vnode.inputLocking) {
          return;
        }
        let oldValue = input.value;
        let newValue = input.value.replace(/[^\d]/g, '');
        if(newValue && binding.value !== 'zeroBefore') {
          newValue = newValue.replace(/^\b(0+)/gi, '') // 不指定可以以0开头的时候 去掉开头多余的0
        }
        // 判断是否需要更新,避免进入死循环
        if(newValue !== oldValue) {
          input.value = newValue
          // 通知v-model更新 vue底层双向绑定实现的原理是基于监听input事件
          input.dispatchEvent(new Event('input')) 
        }
      })
    }
  },
  // 限制能输入小数点后两位的正小数
  inputFloat: {
    bind(el, binding, vnode) {
      let input = vnode.elm;
      input.addEventListener('compositionstart', () => {
        vnode.inputLocking = true
      })
      input.addEventListener('compositionend', () => {
        vnode.inputLocking = false
        input.dispatchEvent(new Event('input'))
      })
      input.addEventListener('input', () => {
        if(vnode.inputLocking) {
          return;
        }
        let oldValue = input.value;
        let newValue = input.value;
        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 = newValue.replace(/^\b(0+)/gi, '') // 去掉开头多余的0
        }
        // 判断是否需要更新,避免进入死循环
        if(newValue !== oldValue) {
          input.value = newValue
          input.dispatchEvent(new Event('input')) // 通知v-model更新
        }
      })
      // input 事件无法处理小数点后面全是零的情况 因为无法确定用户输入的0是否真的应该清除,如3.02。放在blur中去处理
      input.addEventListener('blur', () => {
        let oldValue = input.value;
        let newValue = input.value;
        if(newValue) {
          newValue = Number(newValue).toString()
        }
        // 判断是否需要更新,避免进入死循环
        if(newValue !== oldValue) {
          input.value = newValue
          input.dispatchEvent(new Event('input')) // 通知v-model更新
        }
      })
    }
  }
}

标签: Vue

评论已关闭