需求:在form表单输入框中输入时自动过滤掉所有非数字字符
首先,实现这个需求有很多种方式,第一种是element ui中form表单自带规则校验,但是这样的坏处是每个输入框都要写上表单校验,十分的不方便。第二种是封装一个筛选方法,在每个输入框中的input事件调用这个方法,以下是过滤方法以及使用:
/**
* 格式化数字 只保留整数
*/
export const formatInteger = (val: String | Number, ruleForm?: any, key?: any) => {
val = String(val)
val = val.replace(/[^\d]/g, '') //清除"数字"以外的字符
// 整数大于两位不能0开头
if(val.length>1&&String(val[0])==='0'){
val = val.substring(1);
}
if(ruleForm&&key){
ruleForm[key] = val
}
return val
}
<ElInput v-model="obj.wealthAccBuyNum"
@input="formatInteger(obj.wealthAccBuyNum, obj, 'wealthAccBuyNum')" />
但这个方法的缺点是代码的可读性较差,每个事件都要传递参数造成代码冗余。因此我们使用第三种方法,自定义指令。
第一步:在src中创建一个directive.ts,文件把以下代码复制进去formatInteger 过滤方法写在上方了。_.debounce为lodash库里的防抖方法。
import type { App } from 'vue'
import _ from 'lodash'
import { formatInteger } from './format'
export function filterSensitiveWords(app: App) {
app.directive('filter', {
//在绑定元素的父组件被挂载后调用
mounted(el, binding) {
el.addEventListener('input', inputNumber)
},
//卸载
unmounted(el) {
el.removeEventListener('input', inputNumber)
}
})
}
const inputNumber = _.debounce((event: any) => {
const input = event.target.value
if (!input) {
return
}
const filteredInput = formatInteger(input)
event.target.value = filteredInput
event.target.dispatchEvent(new Event('input'))
}, 300)
第二步:在全局main.ts中挂载指令
// directive文件我放在utils文件夹里面了
import { filterSensitiveWords } from '@/utils/directive'
const app = createApp(App)
filterSensitiveWords(app) //挂载指令
第三步:在需要实现功能的input输入框中使用自定义指令
<ElInput v-model="obj.wealthAccBuyNum" placeholder="请输入" v-filter />