vue directive自定义指令封装输入框校验,按钮权限(解决v-model绑定失效问题和数字校验的中文问题)

学习总结:

因业务需求,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
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值