输入框限制的指令 verify.js

/**
 * use: v-verify="'integer'"
 * description: 仅限input元素 && el-input组件上使用
 *              限制输入只能为规定值
 * bindValue: integer || float
 * template:
 *   <input v-verify></input>
 *   <el-input v-verify></el-input>
 */
export default (Vue) => {
  Vue.directive('verify', {
    inserted(el, binding, vnode) {
      const bindValue = binding.value
      if (!bindValue) return

      function NumberVerify(num = 1, type = 1) {
        if (type === 1) {
          return {
            test(value) {
              let reg = null
              reg = new RegExp('^d{0,8}.{0,1}(d{' + num + '})?$')
              // console.log('%c 第37行', 'color:red;font-size:2em')
              // console.log(value)
              return reg.test(value) && !isNaN(Number(value))
            },
            newValue(oldVal) {
              // let newVal = String(Number.parseFloat(oldVal)) //将导致输入时格式掉小数点后面的0
              let newVal = String(oldVal)
              return isNaN(newVal)
                ? ''
                : newVal.slice(0, newVal.indexOf('.') >= 0 ? newVal.indexOf('.') + (num + 1) : newVal.length)
            }
          }
        } else {
          return {
            test(value) {
              let reg = null
              reg = new RegExp('^d{0,8}.[1](d{' + num + '})?$')
              //   console.log('%c 第39行', 'color:red;font-size:2em')
              //   console.log(value)
              //   console.log(typeof value)

              return reg.test(value) && !isNaN(Number(value)) && value.indexOf('.1') < 0 && value !== '-1'
            },
            newValue(oldVal) {
              let newVal = String(Number.parseFloat(oldVal))
              if (newVal === '-1') {
                return Number(newVal).toFixed(num)
              }
              let val = isNaN(newVal)
                ? ''
                : newVal.indexOf('.') >= 0
                ? newVal.split('.')[1].length < num
                  ? newVal + new Array(num - newVal.split('.')[1].length).fill(0).join('')
                  : newVal.slice(0, newVal.indexOf('.') + (num + 1))
                : newVal + ('.' + new Array(num).fill(0).join(''))
              //   console.log('%c 第61行', 'color:red;font-size:2em')
              //   console.log(val)

              return val
            }
          }
        }
      }

      const verify = {
        // 整形,正整数
        integer: {
          test(value) {
            let reg = /^[0-9]+$/
            return reg.test(value)
          },
          newValue(oldVal) {
            let newVal = Number.parseInt(oldVal)
            console.log('newVal: ', newVal)
            return isNaN(newVal) ? '' : newVal
          }
        },
        numberComma: {
          //只能输入数字和逗号
          test(value) {
            let reg = /^[0-9,]+$/
            return reg.test(value)
          },
          newValue(oldVal) {
            return !oldVal ? '' : oldVal.replace(/[^0-9,]/g, '')
          }
        },
        // 整形,正整数和负整数
        negtiveInteger: {
          test(value) {
            let reg = /^(\-?)[0-9]+$/
            return reg.test(value)
          },
          newValue(oldVal) {
            let newVal = Number.parseInt(oldVal)
            console.log('newVal: ', newVal)
            return isNaN(newVal) ? '' : newVal
          }
        },
        // 浮点,非负数
        float: {
          test(value) {
            // let reg = /^[0-9.]+$/
            let reg = /^(\+)?(0|[1-9]\d*)(\.\d+)?$/
            return reg.test(value) && !isNaN(Number(value))
          },
          newValue(oldVal) {
            let newVal = Number.parseFloat(oldVal)
            return isNaN(newVal) ? '' : newVal
          }
        },
        // 浮点,可负数
        floatNegative: {
          test(value) {
            let reg = /^(\-?)[0-9.]+$/
            return reg.test(value) && !isNaN(Number(value))
          },
          newValue(oldVal) {
            let newVal = Number.parseFloat(oldVal)
            if (oldVal == '-') {
              return oldVal
            }
            return isNaN(newVal) ? '' : newVal
          }
        },
        // 最多保留一位小数,超出截断,少不补
        fixedOne: {
          test(value) {
            let reg = /^\d{0,8}\.{0,1}(\d{1})?$/
            return reg.test(value) && !isNaN(Number(value))
          },
          newValue(oldVal) {
            let newVal = String(Number.parseFloat(oldVal))
            return isNaN(newVal)
              ? ''
              : newVal.slice(0, newVal.indexOf('.') >= 0 ? newVal.indexOf('.') + 2 : newVal.length)
          }
        },
        // 最多保留一位小数,超出截断,在blur的时候补0
        fixedOneForce: NumberVerify(1),
        fixedTwoForce: NumberVerify(2),
        fixedThreeForce: NumberVerify(3),
        fixedFourForce: NumberVerify(4),
        fixedFiveForce: NumberVerify(5),
        fixedEightForce: NumberVerify(8),
        fixedTwo: {
          test(value) {
            let reg = /^\d{0,8}\.{0,1}(\d{1,2})?$/
            return reg.test(value) && !isNaN(Number(value))
          },
          newValue(oldVal) {
            let newVal = String(Number.parseFloat(oldVal))
            return isNaN(newVal)
              ? ''
              : newVal.slice(0, newVal.indexOf('.') >= 0 ? newVal.indexOf('.') + 3 : newVal.length)
          }
        },
        fixedFTwo: {
          test(value) {
            let reg = /^(\-)?\d{0,8}\.{0,1}(\d{1,2})?$/
            return reg.test(value)
          },
          newValue(oldVal) {
            let newVal = String(Number.parseFloat(oldVal))
            return isNaN(newVal)
              ? ''
              : newVal.slice(0, newVal.indexOf('.') >= 0 ? newVal.indexOf('.') + 3 : newVal.length)
          }
        },
        fixedThree: {
          test(value) {
            let reg = /^\d{0,8}\.{0,1}(\d{1,2})?$/
            return reg.test(value) && !isNaN(Number(value))
          },
          newValue(oldVal) {
            let newVal = String(Number.parseFloat(oldVal))
            return isNaN(newVal)
              ? ''
              : newVal.slice(0, newVal.indexOf('.') >= 0 ? newVal.indexOf('.') + 4 : newVal.length)
          }
        },
        fixedFour: {
          test(value) {
            let reg = /^\d{0,8}\.{0,1}(\d{1,2})?$/
            return reg.test(value) && !isNaN(Number(value))
          },
          newValue(oldVal) {
            let newVal = String(Number.parseFloat(oldVal))
            return isNaN(newVal)
              ? ''
              : newVal.slice(0, newVal.indexOf('.') >= 0 ? newVal.indexOf('.') + 5 : newVal.length)
          }
        },
        fixedFive: {
          test(value) {
            let reg = /^\d{0,8}\.{0,1}(\d{1,2})?$/
            return reg.test(value) && !isNaN(Number(value))
          },
          newValue(oldVal) {
            let newVal = String(Number.parseFloat(oldVal))
            return isNaN(newVal)
              ? ''
              : newVal.slice(0, newVal.indexOf('.') >= 0 ? newVal.indexOf('.') + 6 : newVal.length)
          }
        },
        uppercase: {
          // 只能输入大写
          test(value) {
            let reg = /[^A-Z]/
            return !reg.test(value)
          },
          newValue(oldVal) {
            return oldVal.toUpperCase()
          }
        },
        phone: {
          // 只能输入数字与空格
          test(value) {
            let reg = /[^0-9 ]/
            return !reg.test(value)
          },
          newValue(oldVal) {
            return oldVal.replace(/[^0-9 ]/g, '')
          }
        },
        noEngLetter: {
          // 不能输入英文字母
          test(value) {
            let reg = /[A-Za-z@::.]/
            return !reg.test(value)
          },
          newValue(oldVal) {
            return oldVal.replace(/[A-Za-z@::.]/g, '')
          }
        },
        english: {
          // 只能英文和空格
          test(value) {
            // let reg = /[^\w ]/g
            let reg = /[^A-Z ]/g
            return !reg.test(value)
          },
          newValue(oldVal) {
            return oldVal.toUpperCase().replace(/[^A-Z ]/g, '')
          }
        },
        noChinese: {
          // 不能输入中文
          test(value) {
            // let reg = /[^\w ]/g
            let reg = /[\u4e00-\u9fa5]/g
            return !reg.test(value)
          },
          newValue(oldVal) {
            return oldVal.replace(/[\u4e00-\u9fa5]/g, '')
          }
        },
        password: {
          // 只能输入英文,数字,点号,下划线
          test(value) {
            // let reg = /[^\w ]/g
            let reg = /[^\a-\z\A-\Z0-9._!@#$%`~]/g
            return !reg.test(value)
          },
          newValue(oldVal) {
            return oldVal.replace(/[^\a-\z\A-\Z0-9._!@#$%`~]/g, '')
          }
        },
        positive: {
          // 0-9999999
          test(value) {
            return false
          },
          newValue(oldVal) {
            if (oldVal === ' ' || isNaN(oldVal)) {
              return ''
            }
            if (oldVal.length > 99) {
              return oldVal.slice(0, 99)
            }
            if (oldVal < 0) {
              return 0
            }
            if (oldVal > 9999999) {
              return 9999999
            }
            return oldVal
          }
        },
        positiveHandred: {
          // 0-100
          test(value) {
            return false
          },
          newValue(oldVal) {
            if (oldVal === ' ' || isNaN(oldVal)) {
              return ''
            }
            if (oldVal.length > 99) {
              return oldVal.slice(0, 99)
            }
            if (oldVal < 0) {
              return 0
            }
            if (oldVal > 100) {
              return 100
            }
            return oldVal
          }
        },
        numberRange: {
          // -9999999--9999999
          test(value) {
            return false
          },
          newValue(oldVal) {
            if (oldVal !== '-' && (isNaN(oldVal) || oldVal === ' ')) {
              return ''
            }
            if (oldVal.length > 99) {
              return oldVal.slice(0, 99)
            }
            if (!isNaN(parseFloat(oldVal))) {
              if (oldVal < -9999999) {
                return -9999999
              }
              if (oldVal > 9999999) {
                return 9999999
              }
            }
            return oldVal
          }
        },
        // 3位整数可带负号
        integerThree: {
          // -9999999--9999999
          test(value) {
            let reg = /^[0-9]+$/
            console.log(value, 'reg.test(value): ', reg.test(value))
            return reg.test(value) && !(value.length > 1 && value.indexOf(0) === 0) && value.length < 4
          },
          newValue(oldVal) {
            console.log('=======================', oldVal.indexOf('-'))
            let num = ''
            let newVal = ''
            if (oldVal.indexOf('-') !== -1) {
              num = oldVal.substring(1, 4)
              newVal = num.length === 0 ? '' : Number(num)
              console.log('newVal: ', newVal)
              return isNaN(newVal) ? '' : '-' + newVal
            } else {
              num = oldVal.substring(0, 3)
              newVal = Number(num)
              return isNaN(newVal) ? '' : newVal
            }
          }
        },
        integerThreePositive: {
          // -9999999--9999999
          test(value) {
            let reg = /^[0-9]+$/
            console.log(value, 'reg.test(value): ', reg.test(value))
            return (
              reg.test(value) &&
              !(value.length > 1 && value.indexOf(0) === 0) &&
              value.length < 4 &&
              value.indexOf('-') > -1
            )
          },
          newValue(oldVal) {
            let newVal = Number(oldVal)
            console.log('newVal: ', newVal)
            return isNaN(newVal) ? '' : newVal.toString().replace('-', '').substring(0, 3)
          }
        }
      }

      const verifyForce = {
        integer: {
          test(value) {
            let reg = /^[0-9]+$/
            return reg.test(value)
          },
          newValue(oldVal) {
            // let newVal = Number.parseInt(oldVal)
            // console.log('newVal: ', newVal, isNaN(newVal))
            return !oldVal ? '' : oldVal.replace(/[^0-9]/g, '')
          }
        },
        numberComma: {
          //只能输入数字和逗号
          test(value) {
            let reg = /^[0-9,]+$/
            return reg.test(value)
          },
          newValue(oldVal) {
            return !oldVal ? '' : oldVal.replace(/[^0-9,]/g, '')
          }
        },
        negtiveInteger: {
          test(value) {
            let reg = /^(\-?)[0-9]+$/
            return reg.test(value)
          },
          newValue(oldVal) {
            // let newVal = Number.parseInt(oldVal)
            // console.log('newVal: ', newVal, isNaN(newVal))
            return !oldVal ? '' : oldVal.replace(/^(\-?)[0-9]+$/g, '')
          }
        },
        //
        // 强制保留一位小数,,少补
        fixedOneForce: NumberVerify(1, 2),
        fixedTwoForce: NumberVerify(2, 2),
        fixedThreeForce: NumberVerify(3, 2),
        fixedFourForce: NumberVerify(4, 2),
        fixedFiveForce: NumberVerify(5, 2),
        positive: {
          // 0-9999999
          test(value) {
            return false
          },
          newValue(oldVal) {
            if (oldVal === ' ' || isNaN(oldVal)) {
              return ''
            }
            if (oldVal.length > 99) {
              return oldVal.slice(0, 99)
            }
            let floatVal = parseFloat(oldVal)
            if (floatVal < 0) {
              return 0
            }
            if (floatVal > 9999999) {
              return 9999999
            }
            return String(floatVal).indexOf('.') > -1 && String(floatVal).split('.')[1].length > 4
              ? floatVal.toFixed(4)
              : floatVal
          }
        },
        positiveHandred: {
          // 0-100
          test(value) {
            return false
          },
          newValue(oldVal) {
            if (oldVal === ' ' || isNaN(oldVal)) {
              return ''
            }
            if (oldVal.length > 99) {
              return oldVal.slice(0, 99)
            }
            let floatVal = parseFloat(oldVal)
            if (floatVal < 0) {
              return 0
            }
            if (floatVal > 100) {
              return 100
            }
            return String(floatVal).indexOf('.') > -1 && String(floatVal).split('.')[1].length > 4
              ? floatVal.toFixed(4)
              : floatVal
          }
        },
        numberRange: {
          // -9999999--9999999
          test(value) {
            return false
          },
          newValue(oldVal) {
            if (oldVal !== '-' && (isNaN(oldVal) || oldVal === ' ')) {
              return ''
            }
            if (oldVal.length > 99) {
              return oldVal.slice(0, 99)
            }
            let floatVal = parseFloat(oldVal)
            if (!isNaN(floatVal)) {
              if (floatVal < -9999999) {
                return -9999999
              }
              if (floatVal > 9999999) {
                return 9999999
              }
            }
            return String(floatVal).indexOf('.') > -1 && String(floatVal).split('.')[1].length > 4
              ? floatVal.toFixed(4)
              : floatVal
          }
        },
        integerThree: verify.integer,
        integerThreePositive: verify.integer,
        integerStart0: {
          // 数字在0到1亿
          test(value) {
            let reg = /^[0-9]+$/
            return reg.test(value) && Number(value) >= 0 && Number(value) <= 1000000000
          },
          newValue(oldVal) {
            let newVal = Number.parseInt(oldVal)
            console.log('newVal: ', newVal)
            return isNaN(newVal) || newVal > 1000000000 ? '' : newVal
          }
        },
        integerStart1: {
          // 数字在1到1亿
          test(value) {
            let reg = /^[0-9]+$/
            return reg.test(value) && Number(value) >= 1 && Number(value) <= 1000000000
          },
          newValue(oldVal) {
            let newVal = Number.parseInt(oldVal)
            console.log('newVal: ', newVal)
            return isNaN(newVal) || newVal < 1 || newVal > 1000000000 ? '' : newVal
          }
        },
        integerStart2: {
          // 数字在2到1亿
          test(value) {
            let reg = /^[0-9]+$/
            return reg.test(value) && Number(value) >= 2 && Number(value) <= 1000000000
          },
          newValue(oldVal) {
            let newVal = Number.parseInt(oldVal)
            console.log('newVal: ', newVal)
            return isNaN(newVal) || newVal < 2 || newVal > 1000000000 ? '' : newVal
          }
        }
      }

      // let val = vnode.data.model && vnode.data.model.value
      // if (val && binding.value) {
      //   if (!verify[binding.value].test(val)) {
      //     let newVal = verify[binding.value].newValue(val)
      //     vnode.componentInstance.$emit('input', newVal)
      //   }
      // }

      let isComponent = false
      if (vnode.componentInstance) isComponent = true

      function getInput(el) {
        if (el.nodeName == 'INPUT') {
          return el
        } else if (el.nodeName == 'DIV' && el.classList.contains('el-input')) {
          return el.querySelector('input')
        } else if (el.classList.contains('el-textarea')) {
          return el.querySelector('textarea')
        }
      }
      // 获取光标位置
      function getSelectPosition(input) {
        let pos

        if (input.selectionStart == input.selectionEnd) {
          pos = input.selectionStart
        } else {
          pos = -1
        }
        return pos
      }

      getInput(el).addEventListener('input', function (event) {
        let value = event.target.value
        if (!value || value == '') return
        if (!verify[bindValue]) return

        if (!verify[bindValue].test(value)) {
          let pos = getSelectPosition(event.target)
          let newVal = verify[bindValue].newValue(value)

          if (isComponent) {
            Vue.nextTick(() => {
              vnode.componentInstance.$emit('input', newVal)

              setTimeout(() => {
                vnode.componentInstance.$emit('input', newVal)
                try {
                  event.target.setSelectionRange && event.target.setSelectionRange(pos, pos)
                } catch (error) {
                  console.log('不支持setSelectionRange')
                }
              }, 0)
            })
          } else {
            Vue.nextTick(() => {
              let vModel = vnode.data.directives.filter((i) => i.rawName == 'v-model')[0]

              if (vModel) {
                new Function(`this.context.${vModel.expression} = ${newVal}`).call(vnode)
              } else {
                event.target.value = newVal
              }

              setTimeout(() => {
                try {
                  event.target.setSelectionRange && event.target.setSelectionRange(pos, pos)
                } catch (error) {
                  console.log('不支持setSelectionRange')
                }
              }, 0)
            })
          }
        }
      })

      getInput(el).addEventListener('blur', function (event) {
        let value = event.target.value
        if (!value || value == '') return

        if (verifyForce[bindValue] && !verifyForce[bindValue].test(value)) {
          let pos = getSelectPosition(event.target)
          let newVal = verifyForce[bindValue].newValue(value)

          if (isComponent) {
            Vue.nextTick(() => {
              vnode.componentInstance.$emit('input', newVal)
            })
          } else {
            Vue.nextTick(() => {
              let vModel = vnode.data.directives.filter((i) => i.rawName == 'v-model')[0]

              if (vModel) {
                new Function(`this.context.${vModel.expression} = ${newVal}`).call(vnode)
              } else {
                event.target.value = newVal
              }
            })
          }
        }
      })
    }
  })
}

posted @ 2024-09-03 09:53  一bottle陈  阅读(11)  评论(0编辑  收藏  举报