背景

项目当中,复杂的页面包含多个表单,并且一些表单分布在不同组件当中,想点击提交按钮提交表单,需要对所有表单进行校验,会变得有些复杂

思路

(1)如果页面的表单不多,可以通过ref找到表单,然后调用表单校验方法
(2)如果页面表单多,并且分布到不同子组件当中,可以通过递归的方式批量找到所有表单,然后调用表单的校验方法

实现

方式1-通过ref查找表单

(a)概述

  • 通过给每个<el-form>组件添加ref属性,然后通过this.$refs.xxx找到表单组件
  • 把所有表单组件的实例放到一个数组当中,然后通过Promise.all方法对表单进行批量校验
  • (b)代码

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.js" type="application/javascript"></script>
        <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/element-ui/2.15.7/index.js" type="application/javascript"></script>
        <link href="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/element-ui/2.15.7/theme-chalk/index.min.css" type="text/css" rel="stylesheet" />
    </head>
    <body>
        <div id="app">
            <!-- 表单1 -->
            <el-form :model="form1" ref="form1Ref">
                <el-form-item label="用户名" prop="username" :rules="[{ required: true, message: '请输入内容', trigger: 'blur' }]">
                    <el-input v-model="form1.username"></el-input>
                </el-form-item>
            </el-form>
            <!-- 表单2 -->
            <el-form :model="form2" ref="form2Ref">
                <el-form-item label="用户名" prop="username" :rules="[{ required: true, message: '请输入内容', trigger: 'blur' }]">
                    <el-input v-model="form2.username"></el-input>
                </el-form-item>
            </el-form>
            <el-button @click="onSubmit">提交</el-button>
        </div>
    </body>
    <script>
    let vm = new Vue({
        el: '#app',
        data(){
            return {
                form1: {
                    username: ''
                },
                form2: {
                    username: ''
                },
                forms: []//表单组件集合
            }
        },
        mounted() {
            this.forms = [this.$refs.form1Ref, this.$refs.form2Ref]
        },
        methods: {
            onSubmit(){
                //批量校验,通过Promise.all
                Promise.all(this.forms.map(t=>t.validate())).then(res=>{
                    console.log(res);
                    console.log('成功');
                }).catch(err=>{
                    console.log(err);
                    console.log('失败');
                })

            }
        }
    })
    let c = vm.$children[0]
    </script>
    </html>

  • 方式2-通过递归方法查找表单

  • (a)概述

  • 通过组件的$children属性获取当前组件所有子组件,然后判断它的options.name是否为ElForm判断它是否是表单组件
  • 通过递归的方式按照上述方式,得到所有的表单组件实例
  • 把所有表单组件的实例放到一个数组当中,然后通过Promise.all方法对表单进行批量校验
  • (b)代码

  • <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.js" type="application/javascript"></script>
        <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/element-ui/2.15.7/index.js" type="application/javascript"></script>
        <link href="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/element-ui/2.15.7/theme-chalk/index.min.css" type="text/css" rel="stylesheet" />
    </head>
    <body>
        <div id="app">
            <!-- 表单1 -->
            <el-form :model="form1" ref="form1Ref">
                <el-form-item label="用户名" prop="username" :rules="[{ required: true, message: '请输入内容', trigger: 'blur' }]">
                    <el-input v-model="form1.username"></el-input>
                </el-form-item>
            </el-form>
            <!-- 表单2 -->
            <el-form :model="form2" ref="form2Ref">
                <el-form-item label="用户名" prop="username" :rules="[{ required: true, message: '请输入内容', trigger: 'blur' }]">
                    <el-input v-model="form2.username"></el-input>
                </el-form-item>
            </el-form>
            <el-button @click="onSubmit">提交</el-button>
        </div>
    </body>
    <script>
    let vm = new Vue({
        el: '#app',
        data(){
            return {
                form1: {
                    username: ''
                },
                form2: {
                    username: ''
                },
                forms: []//表单组件集合
            }
        },
        mounted() {
            this.forms = [this.$refs.form1Ref, this.$refs.form2Ref]
        },
        methods: {
            onSubmit(){
                //批量校验,通过Promise.all
                Promise.all(this.forms.map(t=>t.validate())).then(res=>{
                    console.log(res);
                    console.log('成功');
                }).catch(err=>{
                    console.log(err);
                    console.log('失败');
                })

            }
        }
    })
    let c = vm.$children[0]
    </script>
    </html>