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
    6 引用 • 11 回帖
  • 复盘
    8 引用 • 5 回帖
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    254 引用 • 666 回帖 • 290 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
luomuren
永夜降临之前,你都有改变的资格
融合块、大纲和双向链接
构建你永恒的数字花园
思源笔记是一款本地优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步