vue directive自定义指令封装输入框校验,按钮权限(解决v-model绑定失效问题和数字校验的中文问题)
学习总结:因业务需求,Eelementui封装的表单校验不能满足需求,利用vue的自定义指令封装满足业务的输入框校验,按钮权限指令。参考:https://cn.vuejs.org/v2/guide/custom-directive.html问题描述:修改输入框的值,并没有修改到v-model绑定的值实现代码:一、只能输入三位0-9-a-z的字符串// // 注册一个全局自定义指令 `v-name`
·
学习总结:
因业务需求,Eelementui封装的表单校验不能满足需求,利用vue的自定义指令封装满足业务的输入框校验,按钮权限指令。实现过程遇坑解决记录记录。参考:https://cn.vuejs.org/v2/guide/custom-directive.html
问题描述:
1、修改输入框的值,并没有修改到v-model绑定的值
2、做了数字和字母校验后通过输入法可以输入中文
解决思路:
1、修改输入框的值,并没有修改到v-model绑定的值: vue中其实它通过解析,在@input事件中设置响应,在响应中修改text的值,然后再通过绑定属性v-bind绑定value同步value值。我是通过调用这个回调 vnode.data.model.callback();网上有其他办法试了也可以实现:2、做了数字和字母校验后通过输入法可以输入中文: 通过compositionend和compositionstart事件判断是否处于。参考文章:
https://segmentfault.com/a/1190000009246058
实现代码:
一、只能输入三位0-9-a-z的字符串
// // 注册一个全局自定义指令 `v-name`
Vue.directive('name', {
inserted(el, binding, vnode) { // 当被绑定的元素插入到 DOM 中时
let iscancel = false;
const inputEvent = e => {
if(iscancel){
return false;
}
let value = e.target.value;//为绑定的值
let v=value;
let pat=/^[0-9a-z]{0,}$/;
if(!pat.test(value)){//输入0-9-a-z以外的字符被替换为空格
v=value.replace(value.charAt(value.length-1),'');
}else if(value.length>3){//输入超过三位的字符被替换为空格
v=value.replace(value.substring(3),'');
}
vnode.data.model.callback(v);//改变虚拟节点上v-model的值
}
el.oninput = inputEvent;
//解决输入中文的问题
el.addEventListener('compositionstart',e=>{
iscancel=true;
});
el.addEventListener('compositionend',e=>{
iscancel=false;
inputEvent(e)
});
}
})
二、数字校验
//注册一个全局自定义指令 `v-onlyNumber`
// onlyNumber: 表示输入数字;v-onlyNumber="'+'"表示正数;v-onlyNumber="'-'"表示负数
Vue.directive('onlyNumber', {
inserted(el, binding, vnode) {
const db=binding.value;
let iscancel=false;
const inputEvent=e => {
if(iscancel){
return false;
}
let value = e.target.value;
let v=value;
//验证为空
if(value===undefined||value===null){
e.target.value='';
return false;
}
//非数字
if(isNaN(value)){
//验证"."和"-"以及非数字
if(value==='.'){
v='0.';
}else if(value!=='-'){
v=parseFloat(value);
if(isNaN(v)){
v='';
}
}
}else if(v!==''){
//验证不合法数字
let temp=value.split('.')
if(temp.length>2){
temp.length=2;
}
temp[0]=temp[0]>9||temp[0].length>1?parseInt(temp[0],10):temp[0];//处理00086这种数字
if(Object.is(temp[0],-0)){
temp[0]="-0";
}
v = temp.length==2?temp.join('.'):temp[0];
}
if(db=='+'){
//正数验证
if(v<0){
v=Math.abs(v)
}
}else if(db=='-'){
//负数验证
if(v=='0.'){
v="-"+v;
}else if(v>0){
v="-"+Math.abs(v);
}
}
// e.target.value=v;
if(Object.is(v,-0)){
v="-0";
}
vnode.data.model.callback(v);
}
el.oninput = inputEvent;
//解决输入中文的问题
el.addEventListener('compositionstart',e=>{
iscancel=true;
});
el.addEventListener('compositionend',e=>{
iscancel=false;
inputEvent(e)
});
}
})
三、按钮权限
//privilege: 按钮权限控制
Vue.directive('privilege', {
inserted(el, binding, vnode, oldVnode) {
let btns=vnode.context.$route.meta.btnPrivilege;
let self=(typeof binding.value!=='function'?binding.value:binding.expression)||binding.arg;
if((!!self)&&btns.indexOf(self)==-1){
el?.parentNode?.removeChild(el);
}
}
})
更多推荐
已为社区贡献3条内容
所有评论(0)