原文发布链接:https://juejin.cn/post/7181752966611730492

需求:

  • 可点击新增,自动添加表单。(这个不难v-for即可)
  • 可自定义方法校验添加的表单内容。(需要掌握element组件的规则,本人没有熟读官网,碰壁好多次才整理出来这篇文章。重要的事说3遍:看官网看官网看官网

效果图:
image.png

动态嵌套校验的难点主要是如何绑定prop属性,自定义方法的难点主要是如何在嵌套的基础上设置自定义方法以及如何将v-for的索引传入校验

Form-Item Attributes

参数说明类型可选值默认值
prop表单域 model 字段,在使用 validate、resetFields 方法的情况下,该属性是必填的string传入 Form 组件的 model 中的字段

可看到,这里prop是传入 Form 组件的 model 中的字段。需要注意的是,prop字段是有相对路径的,而不是随意的一个字段名就可以,需要按照element的格式传入相应的字段

form循环嵌套表单

参考官网的“动态增减表单项”绑定prop属性,动态增减可以直接照搬这个示例(官网就是这么强大,你想要的都有)

image.png

image.png

一级嵌套

循环:<div v-for="(work,i) in formdata.jobList" :key="i">
prop绑定::prop="`jobList[${i}].jobContent`"
规则绑定::rules="[{ required: true, message: '作业内容不能为空', trigger: 'blur' }]"

注:prop不能直接使用work.jobContent
jobList[${i}].jobContent是elementui规定的格式,渲染后的结果为jobList[i].jobContent

二级嵌套

循环:<div style="padding: 10px 20px" v-for="(item,j) in work.specialJobList" :key="j">
prop绑定::prop="`jobList[${i}].specialJobList[${j}].type`"
规则绑定::rules="[{ required: true, message: '请选择特殊作业', trigger: 'blur' }]"

动态添加表单

很显然,动态添加只需要改变v-for的数组即可,新增作业活动如下:

<div class="addBox" type="primary" size="mini" @click="addWorkActivity()>
    <img src="static/img/u15.svg" alt="" class="addIcon" ">
    <span class="operate" >新增作业活动</span>
</div>
// 新增作业活动
addWorkActivity(){
    let obj = {jobContent:"",specialJobList:[{type:"",itemsList:[]}]};
    if(!Array.isArray(this.formdata.jobList)){
        this.formdata.jobList = [];
    }
    this.formdata.jobList.push(obj);
},

嵌套中的表单自定义校验规则

这里需要校验作业内容不能为空,且作业内容不能重复,这里需要将修改的内容和动态的数组对比还需要调服务判断数据库中有无相同的内容来校验,就不能使用简单的校验,需要自定义校验validator

绑定自定义函数,使用el-form-itemrules属性的validator。自定义校验可参考官网的自定义校验规则

image.png

image.png

这里写在el-form-item上与其类似,由于是动态绑定的prop属性,所以这里用el-formrules属性很难校验

循环:<div v-for="(work,i) in formdata.jobList" :key="i">
prop绑定::prop="`jobList[${i}].jobContent`"
规则绑定::rules="[{ required: true, validator:(rule, value, callback)=> checkContent(rule, value, callback,i), trigger: ['blur', 'change']}]"
// 表单校验内容是否重复
async checkContent(rule, value, callback,index){
    if (!value) {
        callback(new Error("作业内容不能为空!"));
    } else {
        let isRepeat = false;// 默认不重复
        for(let i = 0; i < this.formdata.jobList.length; i++){
            if (this.formdata.jobList[i].jobContent == value && i !== index){
                isRepeat = true;
                callback(new Error(`已存在相同的作业内容,请重新输入!`));
                return;
            }
        }
        if(!isRepeat){
            // 页面没有重复时 调服务判断数据库中是否有重复
            let params = {
                jobContent:value,
                id:this.formdata.id
            }
            const res = await serviceValid();// 调用服务校验
            if (res.data.body === "已有重复作业活动") {
                callback(new Error(`已存在相同的作业内容,请重新输入!`));
            }
        }
        callback();
    }
}

注:这里使用 validator:(rule, value, callback)=> checkContent(rule, value, callback,i)主要是为了获得当前索引,如果不需要,直接绑定函数名即可:validator:checkContent

checkContent(rule, value, callback){……}

Logo

前往低代码交流专区

更多推荐