关于前端:利用vue自定义指令实现input框输入限制

5次阅读

共计 2306 个字符,预计需要花费 6 分钟才能阅读完成。

始终都想搞一个可能对立解决 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.key
function 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()}
  }
}

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

正文完
 0