/**
* 指令 - 限制输入框
*/
import Vue from 'vue'
import {
Message
} from 'element-ui'
/**
* 输入保留两位小数
* data-multiple: 整倍数
* data-minus: 可输入负数
* max:最大值
* min:最小值
*/
Vue.directive('inputFloat', {
bind (el, binding, vnode) {
const input = el.getElementsByTagName('input')[0]
input.addEventListener('compositionstart', function () {
vnode.inputLocking = true
})
input.addEventListener('compositionend', function () {
vnode.inputLocking = false
input.dispatchEvent(new Event('input'))
})
input.addEventListener('input', function () {
if (vnode.inputLocking) return
const oldValue = input.value
let newValue = input.value
let reg
if (input.dataset.minus) {
reg = /[^-\d.]/g // 可以输入负数
} else {
reg = /[^\d.]/g
}
newValue = newValue.replace(reg, '')
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 && newValue != '-') {
const 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', function () {
const oldValue = input.value
let newValue = input.value
let numValue = Number(newValue)
const maxVal = Number(input.max || undefined)
const minVal = Number(input.min || undefined)
const multiple = Number(input.dataset.multiple || undefined)
// 含有整倍数
if (newValue && !isNaN(multiple) && (numValue % multiple !== 0)) {
newValue = ''
Message && Message(`限制输入:请输入${multiple}的整倍数!`)
}
// 允许设定的最大值
if (newValue && !isNaN(maxVal) && numValue > maxVal) {
numValue = maxVal
}
// 允许设定的最小值
if (newValue && !isNaN(minVal) && numValue < minVal) {
numValue = minVal
}
// 负数情况
if (newValue == '-') newValue = ''
if (newValue == '-0') newValue = '0'
if (newValue) {
newValue = numValue.toFixed(2)
}
// 判断是否需要更新,避免进入死循环
if (newValue !== oldValue) {
input.value = newValue
input.dispatchEvent(new Event('input')) // 通知v-model更新
}
})
}
})
/**
* 输入整数
* data-multiple: 整倍数
* data-minus: 可输入负数
* max:最大值
* min:最小值
*/
Vue.directive('inputInt', {
bind (el, binding, vnode) {
const input = el.getElementsByTagName('input')[0]
input.addEventListener('compositionstart', function () {
vnode.inputLocking = true
})
input.addEventListener('compositionend', function () {
vnode.inputLocking = false
input.dispatchEvent(new Event('input'))
})
input.addEventListener('input', function () {
if (vnode.inputLocking) return
const oldValue = input.value
let newValue = input.value
let reg
if (input.dataset.minus) {
reg = /^0+(\d)|[^-\d]+/g // 可以输入负数
} else {
reg = /^0+(\d)|[^\d]+/g
}
newValue = newValue.replace(reg, '')
if (newValue && newValue != '-') {
newValue = '' + Number(newValue) // 去掉开头多余的0
}
// 判断是否需要更新,避免进入死循环
if (newValue !== oldValue) {
input.value = newValue
input.dispatchEvent(new Event('input')) // 通知v-model更新
}
})
input.addEventListener('blur', function () {
const oldValue = input.value
let newValue = input.value
const numValue = Number(newValue)
const maxVal = Number(input.max || undefined)
const minVal = Number(input.min || undefined)
const multiple = Number(input.dataset.multiple || undefined)
// 含有整倍数
if (newValue && !isNaN(multiple) && (numValue % multiple !== 0)) {
newValue = ''
Message && Message(`限制输入:请输入${multiple}的整倍数!`)
}
// 允许设定的最大值
if (newValue && !isNaN(maxVal) && numValue > maxVal) {
newValue = '' + maxVal
}
// 允许设定的最小值
if (newValue && !isNaN(minVal) && numValue < minVal) {
newValue = '' + minVal
}
// 负数情况
if (newValue == '-') newValue = ''
if (newValue == '-0') newValue = '0'
// 判断是否需要更新,避免进入死循环
if (newValue !== oldValue) {
input.value = newValue
input.dispatchEvent(new Event('input')) // 通知v-model更新
}
})
}
})
/**
* 只能输入字符和数字,排除中文和符号
*/
Vue.directive('inputNE', {
bind (el, binding, vnode) {
const input = el.getElementsByTagName('input')[0]
input.addEventListener('compositionstart', function () {
vnode.inputLocking = true
})
input.addEventListener('compositionend', function () {
vnode.inputLocking = false
input.dispatchEvent(new Event('input'))
})
input.addEventListener('input', function () {
if (vnode.inputLocking) return
const oldValue = input.value
let newValue = input.value
newValue = newValue.replaceAll(
/[\u4e00-\u9fa5/\s+/]|[`~!@#$%^&*() \+ =<>?"{}|., \/ ;' \\ [ \] ·~!@#¥%……&*()—— \+ ={}|《》?:“”【】、;‘’,。、]/g,
'')
// 判断是否需要更新,避免进入死循环
if (newValue !== oldValue) {
input.value = newValue
input.dispatchEvent(new Event('input')) // 通知v-model更新
}
})
}
})
/**
* 限制输入特定字符
*/
let restrictReg = new RegExp("'", 'g') //特定字符正则
Vue.directive('restrict', {
bind (el, binding, vnode) {
let input = ['input', 'textarea'].includes(el.tagName.toLowerCase()) ? el : (el.querySelector('input') || el.querySelector('textarea'))
input.addEventListener('compositionstart', function () {
vnode.inputLocking = true
})
input.addEventListener('compositionend', function () {
vnode.inputLocking = false
input.dispatchEvent(new Event('input'))
})
input.addEventListener('input', () => {
if (vnode.inputLocking) return
const oldValue = input.value
let newValue = oldValue.replace(restrictReg, '');
// 判断是否需要更新,避免进入死循环
if (newValue !== oldValue) {
input.value = newValue
input.dispatchEvent(new Event('input')) // 通知v-model更新
}
});
}
});