温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

vue怎么表单验证validate

发布时间:2021-09-10 18:29:50 来源:亿速云 阅读:1901 作者:柒染 栏目:web开发

vue怎么表单验证(form)validate,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

vue怎么表单验证validate 

1.原理解释

vue怎么表单验证validate

考虑

我们看一下我们可以用form去整体触发校验也可以单个input来触发form-item 进行校验 童鞋们现在可能感觉还是没懂,没关系继续往下看。

2.派发和广播

为什么要用广播和派发呢。通常我们和业务没有关系的组件尽量不要使用vuex和bus(事件总线)。 下面我送上广播和派发的代码。我们在需要调用组件绑上 this.$on('event',res=>()) ,通过派发和广播进行调用 $emit

  • 派发是向上查找且只调用1个

  • 广播是向下查找调用多个

  • 注意⚠️所有的组件都要写上name

  • 通过混合器 mixins 来使用

emitter.js /**  * 递归使用 call 方式this指向  * @param componentName // 需要找的组件的名称  * @param eventName // 事件名称  * @param params // 需要传递的参数  */ function broadcast(componentName, eventName, params) {  // 循环子节点找到名称一样的子节点 否则 递归 当前子节点  this.$children.map(child=>{   if (componentName===child.$options.name) {    child.$emit.apply(child,[eventName].concat(params))   }else {    broadcast.apply(child,[componentName,eventName].concat(params))   }  }) } export default {  methods: {   /**    * 派发 (向上查找) (一个)    * @param componentName // 需要找的组件的名称    * @param eventName // 事件名称    * @param params // 需要传递的参数    */   dispatch(componentName, eventName, params) {    let parent = this.$parent || this.$root;//$parent 找到最近的父节点 $root 根节点    let name = parent.$options.name; // 获取当前组件实例的name    // 如果当前有节点 && 当前没名称 且 当前名称等于需要传进来的名称的时候就去查找当前的节点    // 循环出当前名称的一样的组件实例    while (parent && (!name||name!==componentName)) {     parent = parent.$parent;     if (parent) {      name = parent.$options.name;     }    }    // 有节点表示当前找到了name一样的实例    if (parent) {     parent.$emit.apply(parent,[eventName].concat(params))    }   },   /**    * 广播 (向下查找) (广播多个)    * @param componentName // 需要找的组件的名称    * @param eventName // 事件名称    * @param params // 需要传递的参数    */   broadcast(componentName, eventName, params) {    broadcast.call(this,componentName, eventName, params)   }  } }

3.async-validator

不懂 async-validator 可以去官网看看 github

yarn add async-validator // 因为当前这个插件是需要打包到项目里的所以不能加-D

4.api设计

我们看一下下面 element 官网的图`

form 有2个注入的字段 :rules 规则,和 :model 当前form的值会通过 model 的值和 rules 进行匹配来进行校验.

form-item 有2个注入的字段 lableprop ( prop )是来和 form 进行匹配来获取当前的 form-item 的值的

input 其实有当前的 @input 的方法。 v-model 就不解释了

vue怎么表单验证validate 

form

我们在 form 先开始注入当前所有的 form-item 实例(获取)

created 会在生命周期开始的时候绑定和删除当前实例的方法。通常绑定都在页面dom开始前调用需要在 dom 加载完

provide 配合inject 使用让子组件可以调用当前父组件的方法以及data

下面都写了备注可以放心食用(经过测试当前是可以进行校验的)

form.vue <template>  <form>   <slot></slot>  </form> </template> <script>  export default {   name: "aiForm",   provide(){ // [不懂的可以看看](https://cn.vuejs.org/v2/api/#provide-inject)    return {     form: this    }   },   props: {    // 当前 form 的model    model: {     type: Object    },    // 验证    rules: {     type: Object    }   },   data(){    return{     fields: [] // 储存当前的 form-item的实例    }   },   created(){    // 存当前实例    let that =this;    this.$on('on-form-item-add',item=>{     if (item) {      that.fields.push(item)     }    });    // 删除当前有的实例    this.$on('on-form-item-remove',item=>{     if (item.prop) {// 如果当前没有prop的话表示当前不要进行删除(因为没有注入)      that.fields.splice(that.fields.indexOf(item),1)     }    })   },   methods:{    /**     * 清空     */    resetFields(){//添加resetFields方法使用的时候调用即可     /**      * 当前所有当form-item 进行赋值      */     this.fields.forEach(field => {      field.resetField();     });    },    /**     * 校验 公开方法:全部校验数据,支持 Promise     */    validate(callback){     return new Promise(resolve=>{      /**       * 当前所有当form-item 进行校验       */      let valid = true; // 默认是通过      let count = 0; // 来匹配当前是否是全部检查完      this.fields.forEach(field => {       // 每个实例都会有 validation 的校验的方法       field.validation('',error=>{        // 只要有一个不符合那么当前的校验就是未通过的        if (error) {          valid = false;        }        // 通过当前检查完所有的form-item的时候才会调用        if (++count === this.fields.length) {         resolve(valid);// 方法使用then         if (typeof callback === 'function') {          callback(valid);// 直接调用注入的回调方法         }        }       });      });     })    }   }  } </script>

5.form-item

  •  form-item比较复杂我们一个一个讲

  • isRequired来判断当前是否需要必填

  • validateState来判断当前校验的状态

  • validateMessage当前的错误的值

  • inject: ['form'] 我们就可以通过this.from.xxx来调用父组件的事件以及值了

  • computed下的fieldValue可能在不停的变化所以我们通过计算属性来使用

  • initialValue 默认的值我们在mounted的时候且当前需要进行校验的时候(prop有的时候)会赋值

  • mixins: [Emitter]混合器就是里面的方法以及date都可以在当前调用使用频繁的都可以放在混合器里面

  • 我们form-item 会传入input的两个方法blur和change(input原生使用的@input)通过form传入的校验rules里面的trigger来判断

form-item.vue <template>  <div>   <label :class="isRequired?'ai-form-item-label-required':''">{{label}}</label>   <div>    <slot></slot>    <div class="ai-form-item-message" v-if="validateState==='error'">{{validateMessage}}</div>   </div>  </div> </template> <script>  import Emitter from '../../mixins/emitter';  import schema from 'async-validator';  export default {   name: "aiFormItem",   mixins: [Emitter],   inject: ['form'],   props: {    label: {     type: String,     default: ''    },    prop:{     type: String    },   },   computed:{    fieldValue () {     return this.form.model[this.prop];    },   },   data(){    return {     initialValue: '', // 储存默认值     isRequired: false, // 当前的是否有问题     validateState: '', // 是否校验成功     validateMessage: '', // 校验失败文案    }   },   methods:{    /**     * 绑定事件 进行是否 required 校验     */    setRules(){     let that = this;     let rules = this.getRules();//拿到父组件过滤后当前需要使用的规则     if (rules.length) {      // every 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)      // some 只要有一个符合就返回true      this.isRequired = rules.some(rule=>{       // 如果当前校验规则中有必填项,则标记出来       return rule.required;      })     }     /**      * blur 事件      */     this.$on('on-form-blur',that.onFieldBlur);     /**      * change 事件      */     this.$on('on-form-change',that.onFieldChange)    },    /**     * 从 Form 的 rules 属性中,获取当前 FormItem 的校验规则     */    getRules () {     let that = this;     let rules = that.form.rules;     rules = rules?rules[that.prop]:[];     return [].concat(rules||[])//这种写法可以让规则肯定是一个数组的形式    },    /**     * Blur 进行表单验证     */    onFieldBlur(){     this.validation('blur')    },    /**     * change 进行表单验证     */    onFieldChange(){     this.validation('change')    },    /**     * 只支持 blur 和 change,所以过滤出符合要求的 rule 规则     */    getFilteredRule (trigger) {     let rules = this.getRules();     // !res.trigger 没有调用方式的时候默认就校验的     // filter 过滤出当前需要的规则     return rules.filter(res=>!res.trigger || res.trigger.indexOf(trigger)!==-1)    },    /**     * 校验数据     * @param trigger 校验类型     * @param callback 回调函数     */    validation(trigger,callback=function () {}){     // blur 和 change 是否有当前方式的规则     let rules = this.getFilteredRule(trigger);     // 判断当前是否有规则     if (!rules || rules.length === 0) {      return     }     // 设置状态为校验中     // async-validator的使用形式     this.validateState = 'validating';     var validator = new schema({[this.prop]: rules});     // firstFields: true 只会校验一个     validator.validate({[this.prop]: this.fieldValue}, { firstFields: true },(errors, fields) => {      this.validateState = !errors ? 'success' : 'error';      this.validateMessage = errors ? errors[0].message : '';      callback(this.validateMessage);     });    },    /**     * 清空当前的 form-item     */    resetField(){     this.form.model[this.prop] = this.initialValue;    }   },   // 组件渲染时,将实例缓存在 Form 中   mounted(){    // 如果没有传入 prop,则无需校验,也就无需缓存    if (this.prop) {     this.dispatch('aiForm','on-form-item-add', this);     // 设置初始值,以便在重置时恢复默认值     this.initialValue = this.fieldValue;     // 添加表单校验     this.setRules()    }   },   // 组件销毁前,将实例从 Form 的缓存中移除   beforeDestroy(){    this.dispatch('iForm', 'on-form-item-remove', this);   },  } </script> <style scoped>  <!--当前css-->  .ai-form-item-label-required:before{   content: '*';   color: red;  }  .ai-form-item-message {   color: red;  } </style>

5.input

  •  value 支持一个入参

  • 因为当前是一个 input 注入的参数是不能直接放到 input 里面使用的所以先赋值给了 defaultValue 然后用 watch 来不停给 defaultValue 赋值达到一个父组件修改后的一个绑定

<template>  <input type="text"    @input="handleInput" // change    @blur="handleBlur"    :value="defaultValue"  > </template> <script>  import Emitter from '../../mixins/emitter.js'  export default {   name: "aiInput",   mixins: [Emitter],   props: {    value: {     type: String,     default: ''    }   },   data(){    return {     defaultValue: this.value    }    },   watch:{    value (val) {     this.defaultValue = val;    }   },   methods:{    /**    * change 事件    * @param event    */    handleInput(event){     // 当前model 赋值     this.defaultValue = event.target.value;     // vue 原生的方法 return 出去     this.$emit('input',event.target.value);     // 将当前的值发送到 aiFormItem 进行校验     this.dispatch('aiFormItem','on-form-change',event.target.value)    },    /**    * blur 事件    * @param event    */    handleBlur(event){     // vue 原生的方法 return 出去     this.$emit('blur',event.target.value);     // 将当前的值发送到 aiFormItem 进行校验     this.dispatch('aiFormItem','on-form-blur',event.target.value)    }   }  } </script>

最后

最后给上一个当前可以的使用方式

<template>  <div class="home">  <button @click="changeButton">测试</button>  <ai-form ref="formItems" :model="formValidate" :rules="ruleValidate">   <ai-form-item label="用户名" prop="name">   <ai-input v-model="formValidate.name"/>   </ai-form-item>  </ai-form>  </div> </template> <script>  import AiForm from "../components/form/form";  import AiFormItem from "../components/form/form-item";  import AiInput from "../components/input/ai-input"; export default {  name: 'home',  components: {AiInput, AiFormItem, AiForm},],  data(){   return{    formValidate: {     name: '123z',     mail: ''    },    ruleValidate: {     name: [      { required: true, message: '用户名不能为空', trigger: 'blur' },     ],    }   }  },  methods:{   changeButton(){    this.$refs.formItems.resetFields() // 清空方法    this.$refs.formItems.validate() // 验证方法     .then(res=>{      console.log(res)     })   }  }, } </script>

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI