自定义vue必填验证指令

 当focus时提示的文字组件可以改成alert

调用方法:

v-required="{
model:obj,attr:'userName'
,msg:'用户姓名为必填项'
,ref:'userName'
,callback:'backFunName'
,requiredfun:'funName'
,requiredfunPar:item
,valType:'number'
,valMin:0
,valMax:100}"

//vue指定取值 用的
var _VUECOMMON = {
    getValue:function($this,json,attrName){
        let r="";
        if(json && attrName) {
            r = json[attrName];
        }else{
            //因为取vue Data第一级的数据,获取不到,只能用这样的方式来取
            r=$this[attrName];
        }
        return r;
    },
    setValue:function(vnode,json,attrName,val){
        if(json && attrName){
            json[attrName] = val;
        }else{
            //因为取vue Data第一级的数据,获取不到,只能用这样的方式来取
            $this[attrName] = val;
        }
    },
}
//====================================vue必填验证指令开始====================================2020-10-21
!function ($vue) {
//验证指令使用说明(这个指令一定要放在vue.warning后面,因该指令用到了vue.warning来提示)
//最简单的引用:v-required="{model:obj,attr:'userName'}"
//最推荐的引用:v-required="{model:obj,attr:'userName',field:'用户名'}"
//自定义组件引用:v-required="{model:obj,attr:'userName',field:'用户名',ref:'refId'}"
//最全参数引用:v-required="{model:obj,attr:'userName',msg:'用户姓名为必填项',ref:'userName',callback:'backFunName',requiredfun:'funName',requiredfunPar:item,valType:'number',valMin:0,valMax:100}"
//调用验证方法:if(this.checkRequired(this)){//验证通过可以进行保存}
//参数说明
// model:obj,//Data中的Model变量名,如果直接Data第一级可以不带该参数
// attr:'userName',//Model变量的属性名,(必填参数)
// field:'User Name',//focus时提示的字段名称
// msg:'custom msg ',//focus时自定义提示的文字,(当指定了该参数,field无效)
// ref:'refIdName',//当自定义组件时,指定了Ref时使用,如输入提示组件<multiselect ref="refIdName">
// callback:'backFunName',//当得到焦点focus()以后调用该方法
// requiredfun:'funName',//必填条件判断方法,该方法必须返回Boolean值,当得条件满足才进行必填验证,否则跳过
// requiredfunPar:'funName',//必填条件判断方法的参数,
// valType:'number',//验证数据类型,int整数,intN:正整数,number:数字,numberN:正数字
// valMin:0,    //验证数据类型为数字时,最小值
// valMax:100,  //验证数据类型为数字时最大值
    $vue.directive('required', {
        bind: function (el, binding, vnode) {
            //console.log("===============================================bind")
            //所有需要必填的全放在Vue.prototype._requiredList
            if (Vue.prototype._requiredList) {
                Vue.prototype._requiredList.push({"el": el, "binding": binding, "vnode": vnode})
            } else {
                Vue.prototype._requiredList = [{"el": el, "binding": binding, "vnode": vnode}];
            }
        },
        update:function(el, binding, vnode){
            //console.log("===============================================update")
            if (Vue.prototype._requiredList) {
                var arr=Vue.prototype._requiredList;
                for (let i in arr) {
                    var item = arr[i];
                    if(item.el==el){
                        //因为数据修改以后整个model数据发生改变了,所以需要修改_requiredList中的值
                        item.binding=binding;
                        item.vnode=vnode;
                    }
                }
            }
        }
    });
    Vue.prototype.checkRequired = function ($this) {
        // console.log($this._requiredList)
        let arr = $this._requiredList;//从Vue.prototype._requiredList中取出必填验证的对象
        for (let i in arr) {
            var item = arr[i];
            var option = item.binding.value || {};//参数
            // console.log("===============================================")
            // console.log(option)
            var modelValue = _VUECOMMON.getValue($this, option.model, option.attr);//得到值
            //console.log("modelValue:"+modelValue)
            var isRequired = true;//是否需要必填判定
            if (option.requiredfun && typeof (option.requiredfun) == "function") {
                //验证条件的方法
                //console.log("======requiredfun====")
                isRequired =option.requiredfun(option.requiredfunPar);
            }

            //跳转到focus的对象
            var toFocus=function(msg){
                var focusDom=null;
                if (option.ref) {
                    if($this.$refs[option.ref].$el){//vue组件 (对象,非数组格式)
                        focusDom=$this.$refs[option.ref].$el;
                    }else if ($this.$refs[option.ref][0]) {//vue组件 (数组格式)
                        focusDom=$this.$refs[option.ref][0].$el;
                    }else{
                        focusDom=$this.$refs[option.ref];//非组件 (普通的DOM元素)
                    }
                } else {
                    focusDom=item.el;//非组件 (普通的DOM元素)
                }
                if(focusDom.offsetParent && !focusDom.disabled && !focusDom.readOnly){
                    //$this.warning(msg);
            alert(msg);//可以改成你的输入提示组件方法 focusDom.focus();
//回调函数 if (typeof (option.callback) === 'function') { option.callback(item.el, item.binding,item.vnode); } return true;//onfocus成功 }else{ //如果dom display:none or disabled or readOnly,不进行focus; console.log("[v-required warning]this dom display:none or disabled or readOnly,can't focus:"); console.log(focusDom); return false;//onfocus失败 } } //null 或 '‘ 或 [] 或 {} 都能验证为空 if (isRequired && (null==modelValue || ''==modelValue || '[]'==JSON.stringify(modelValue) || '{}'==JSON.stringify(modelValue))) { var showMsg=""; if (option.msg) { showMsg=option.msg; } else if (option.field) { showMsg=option.field + ' is required'; } else { showMsg='This is required'; } if(toFocus(showMsg)){return false;} } //数据类型验证开始 if(modelValue != null && modelValue != '' && option.valType){ var isFocus=false; var showMsg=""; if(option.valType=="int"){//如果不是整数 if(parseInt(modelValue).toString() == "NaN" || parseInt(modelValue)!=modelValue){ isFocus=true; showMsg=(option.field || 'this') + ' is integer!'; } }else if(option.valType=="intN"){//如果不是正整数 if(parseInt(modelValue).toString() == "NaN" || parseInt(modelValue)!=modelValue || modelValue<0){ isFocus=true; showMsg=(option.field || 'this') + ' is positive integer!'; } }else if(option.valType=="number"){//如果不是数字 if(parseFloat(modelValue).toString() == "NaN"){ isFocus=true; showMsg=(option.field || 'this') + ' is number!'; } }else if(option.valType=="numberN"){//如果不是正数字 if(parseFloat(modelValue).toString() == "NaN" || modelValue<0){ isFocus=true; showMsg=(option.field || 'this') + ' is positive number!'; } } if(!isFocus && (option.valMin || option.valMax)){ //如果小于指定的最小值 if(option.valMin && parseFloat(modelValue).toString() != "NaN" && modelValue<option.valMin) { isFocus = true; msg = (option.field || 'this') + ' Must be greater than '+option.valMin+' !'; } //如果大于指定的最大值 if(option.valMax && parseFloat(modelValue).toString() != "NaN" && modelValue>option.valMax) { isFocus = true; msg = (option.field || 'this') + ' Must be less than '+option.valMax+' !'; } } if(isFocus) { if(toFocus(showMsg)){return false;} } } } return true;//如果验证全通过返回true } }(Vue); //====================================vue必填验证指令结束====================================
原文地址:https://www.cnblogs.com/q149072205/p/13852180.html