永夜-Evernight

永夜降临之前,你都有改变的资格

ElementUI动态循环表单

公司有这样一个需求,需要对用户表字段进行动态扩展,我的做法是新建了一张扩展字段表,一张扩展字段值表,现在需要将扩展字段表中新增的字段循环放入用户添加的form表单中,并需要控制动态表单的必填项,以下是过程复盘:

为了方便,此处未实现扩展字段相关代码,前端获取的数据直接在后端初始化

环境

jdk:jdk1.8.0_51

框架:若依分离版(RuoYi-Vue_v3.8.3)

框架地址:https://gitee.com/y_project/RuoYi-Vue.git

复盘主要代码:https://gitee.com/lmr-replay/replay-elementUIdtxhbd.git

实现过程

1. 获取列表

在data()中添加字段列表属性:

fileds: []

在用户新增按钮的方法handleAdd()中添加获取扩展字段的方法

/** 新增按钮操作 */
handleAdd() {
  this.reset();
  getUser().then(response => {
    this.postOptions = response.posts;
    this.roleOptions = response.roles;
    this.open = true;
    this.title = "添加用户";
    this.form.password = this.initPassword;
    getFileds().then(res => {
      this.fileds = res.data
    });
  });
},

获取到所有扩展字段的列表

{
"msg": "操作成功",
"code": 200,
"data": [
{"filedId": 0,"filedLabel": "家庭住址","filedName": "address","filedType": "text","doubleLayout":"N","requiredFiled": "Y","filedValue": null},
{"filedId": 1,"filedLabel": "出生年月","filedName": "birth","filedType": "date","doubleLayout":"Y","requiredFiled": "Y","filedValue": null},
{"filedId": 2,"filedLabel": "学历","filedName": "record","filedType": "select","doubleLayout":"Y","requiredFiled": "N","filedValue": null}
> ]
}

2. 循环生成表单

在用户新增弹出框的备注字段下方,加入扩展字段表单

<el-divider content-position="center">扩展属性</el-divider>
<el-row>
  <el-col :span="24" v-for="(filed, index) in fileds" :key="filed.filedId">
    <el-form-item :label="filed.filedLabel" :rules="filed.requiredFiled==='Y'?[{required: true, message: '域名不能为空', trigger: 'blur'}]:[]">
      <el-input v-if="filed.filedType==='text'" v-model="filed.value" type="text" placeholder="请输入"></el-input>
      <el-date-picker v-else-if="filed.filedType=='date'" v-model="filed.value" type="date" placeholder="请选择"></el-date-picker>
      <el-select v-else-if="filed.filedType==='select'" v-model="filed.value" placeholder="请选择">
        <el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId" :disabled="item.status == 1"></el-option>
      </el-select>
    </el-form-item>
  </el-col>
</el-row>

image-20220828162006-6d2577i.png

  • 此时发现一个问题,虽然出现了必填字段的*标识,但是无法控制其必填

3. 解决必填项控制失败问题

从网上找了一下相关只是,发现需要添加prop(形式为:'fileds.'+index+'.value'),于是修改如下:

<el-divider content-position="center">扩展属性</el-divider>
<el-row>
  <el-col v-for="(filed, index) in fileds" :key="filed.filedId" :span="filed.doubleLayout==='Y'?12:24">
    <el-form-item :label="filed.filedLabel"
                  :prop="'fileds.'+index+'.value'"
                  :rules="filed.requiredFiled==='Y'?[{required: true, message: '域名不能为空', trigger: 'blur'}]:[]"
    >
      <el-input v-if="filed.filedType==='text'" v-model="filed.value" type="text" placeholder="请输入"></el-input>
      <el-date-picker v-else-if="filed.filedType=='date'" v-model="filed.value" type="date" placeholder="请选择"></el-date-picker>
      <el-select v-else-if="filed.filedType==='select'" v-model="filed.value" placeholder="请选择">
        <el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId" :disabled="item.status == 1"></el-option>
      </el-select>
    </el-form-item>
  </el-col>
</el-row>
  • 此时打开添加弹框,会出现异常:Error: please transfer a valid prop path to form item!

4. 解决异常:Error: please transfer a valid prop path to form item!

从网上找了一下相关异常信息,发现是prop绑定值有问题,fileds需要是form中的一个属性,于是修改代码,将获取到的字段列表放入form中:

getFileds().then(res => {
  this.form.fileds = res.data
});

并修改页面代码,循环form.fileds

<el-divider content-position="center">扩展属性</el-divider>
<el-row>
  <el-col v-for="(filed, index) in form.fileds" :key="filed.filedId" :span="filed.doubleLayout==='Y'?12:24">
    <el-form-item :label="filed.filedLabel"
                  :prop="'fileds.'+index+'.value'"
                  :rules="filed.requiredFiled==='Y'?[{required: true, message: '域名不能为空', trigger: 'blur'}]:[]"
    >
      <el-input v-if="filed.filedType==='text'" v-model="filed.value" type="text" placeholder="请输入"></el-input>
      <el-date-picker v-else-if="filed.filedType=='date'" v-model="filed.value" type="date" placeholder="请选择"></el-date-picker>
      <el-select v-else-if="filed.filedType==='select'" v-model="filed.value" placeholder="请选择">
        <el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId" :disabled="item.status == 1"></el-option>
      </el-select>
    </el-form-item>
  </el-col>
</el-row>

很好,异常消失了,并且状态判断也没有问题:

image-20220828164031-nbdumio.png

  • 但是又发现了新的问题:表单无法输入

5. 解决动态表单无法输入问题

通过百度发现这个问题是因为我们获取到的字段列表是直接赋值给form的,但是在form初始化的时候并未在form中定义fileds变量,只需要在初始化form时定义fileds变量即可

修改reset()方法,在form中定义fileds变量

// 表单重置
reset() {
  this.form = {
    userId: undefined,
    deptId: undefined,
    userName: undefined,
    nickName: undefined,
    password: undefined,
    phonenumber: undefined,
    email: undefined,
    sex: undefined,
    status: "0",
    remark: undefined,
    postIds: [],
    roleIds: [],
    fileds: [] // 此处非常关键
  };
  this.resetForm("form");
},

至此,动态表单就可以进行必填控制并可以输入值了,复盘到此结束!

联系方式

作者:永夜

邮箱:Evernight@aliyun.com

以上内容有不正确的地方烦请指正!🙏🙏🙏


标题:ElementUI动态循环表单
作者:luomuren
地址:http://luomuren.top/articles/2022/08/28/1661677593505.html