始终都想搞一个可能对立解决input框限度的小工具,最近新我的项目有须要,就借鉴了一下大佬们的文档博客,本人记录一下。
废话不多说,间接上代码:

//index.vue

<template>// 纯数字<el-input v-input-filter:num="ruleForm.warningNum" v-model="ruleForm.warningNum" placeholder="请输出数字"></el-input>// 纯数字 + 小数点<el-input v-input-filter:num.point="ruleForm.warningNum" v-model="ruleForm.warningNum" placeholder="请输出数字"></el-input></template>

// directive.js

import Vue from 'vue'// 限度只能输出数字 小数点的限度由修饰符管制const onlyNum = (el, bindings, vnode) => {  let regExp = /[^\d]/g  if (bindings.modifiers['point']) {    // 修饰符 ‘point’    regExp = /[^\d\.]/g  }  fnSaveCursorPos(el, bindings, vnode, regExp)}// 限度只能输出字母(蕴含大小写字母)const onlyLetter = (el, bindings, vnode) => {  let regExp = /[^a-z|A-Z]/g  if (bindings.modifiers['point']) {    // 修饰符 ‘point’    regExp = /[^a-z|A-Z|.]/g  }  fnSaveCursorPos(el, bindings, vnode, regExp)}// 限度只能输出字母和数字(蕴含大小写字母)const onlyLetterNum = (el, bindings, vnode) => {  let regExp = /[^a-z|A-Z\d]/g  fnSaveCursorPos(el, bindings, vnode, regExp)}Vue.directive('input-filter', {  update(el, bindings, vnode) {    switch (bindings.arg) {      case 'num':        onlyNum(el, bindings, vnode)        break      case 'letter':        onlyLetter(el, bindings, vnode)        break      case 'num-letter':        onlyLetterNum(el, bindings, vnode)        break      default:        console.log('此办法暂无减少')        break    }  }})// 解决光标地位,防止从新赋值之后光标呈现在开端function fnSaveCursorPos(el, bindings, vnode, regExp) {  bindings.value = bindings.value + ''  let inputEl = el  if (el.tagName !== 'INPUT') {    inputEl = el.querySelector('input')  }  if (!inputEl) {    console.log('没有input')    return  }  const inputElCursorPos = inputEl.selectionStart // 输入框输出之后的光标地位  const regExpStringLength = (bindings.value.match(regExp) || []).length // 被革除的字符长度  fnSetVal(vnode.context, bindings.expression, bindings.value.replace(regExp, ''))  inputEl.setSelectionRange(inputElCursorPos - regExpStringLength, inputElCursorPos - regExpStringLength)  const timer = setTimeout(() => {    // console.log('inputEl', inputElCursorPos - regExpStringLength)    clearTimeout(timer)    inputEl.setSelectionRange(inputElCursorPos - regExpStringLength, inputElCursorPos - regExpStringLength)  })}// 赋值解决, 例如:obj.key.keyfunction fnSetVal(data, fields, setVal) {  if (Object.prototype.toString.call(data) === '[object Object]' && Object.prototype.toString.call(fields) === '[object String]') {    const keys = fields.split('.')    let value = data    while (keys.length && value !== undefined) {      if (keys.length === 1) {        value[keys[0]] = setVal        return      }      value = value[keys[0]]      keys.shift()    }  }}

利用自定义指令中‘更新’的生命周期来对绑定的值进行解决,然而这个会有两次的更新过程,第一次是原始值触发更新,第二次是解决限度之后触发的更新;感觉这里有点不太完满。
文章中如果有什么问题,欢送指出~~~ 感激!!!