likes
comments
collection
share

表单的批量校验

作者站长头像
站长
· 阅读数 40

概述

背景

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

思路

(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">
            <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">
            <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>
         <!-- 表单3 -->
        <my-son></my-son>
    </div>
</body>
<script>
Vue.component('my-son',{
    data(){
        return {
            form: {
                username: ''
            }
        }
    },
    template: `
        <div>
            <el-form :model="form" >
                <el-form-item label="用户名" prop="username" :rules="[{ required: true, message: '请输入内容', trigger: 'blur' }]">
                    <el-input v-model="form.username"></el-input>
                </el-form-item>
            </el-form>
        </div>
    `
})
let vm = new Vue({
    el: '#app',
    data(){
        return {
            form1: {
                username: ''
            },
            form2: {
                username: ''
            },
            forms: []//表单组件集合
        }
    },
    mounted() {
        //通过递归的方式在组件树中找到表单组件
        this.findFormComponent(this.$children)
    },
    methods: {
        //递归方法
        findFormComponent(children) {
            children.forEach((item) => {
                if (item.$options.name === 'ElForm') {
                    this.forms.push(item)
                } else {
                    item.$children && this.findFormComponent(item.$children)
                }
            })
        },
        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>
转载自:https://juejin.cn/post/7247504715726241850
评论
请登录