2020-06-14

new Vue({
  el: '#app',
  data() {
    return {
      dataInt: 0,
      dataFloat: 0
    }
  },
  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) {
            let 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', () => {
          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更新
          }
        })
      }
    }
  }
})

你可能感兴趣的:(2020-06-14)