/**
* 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
}
})
}
}
})
}
})
}