前言
现在是2022年5月3日11:47:15!劳动节假期已经过去了三天了,今天是被封家里的第7天,也是解封的第一天。
说实话,在家里的工作效率一点都不如公司的高,这两天完善了下系统中一个复杂表单的操作,大致实现的是这样的功能:
- 一个设备下是可以添加多个采集类型的
- 每个采集类型下面可以添加多个元素个数
- 根据元素个数不同,来添加其他信息
由于内容有点多,所以我分了三篇来整理,分别是:
- element ui实现多层级复杂表单的操作(添加与回显)之表单操作交互操作
- element ui实现多层级复杂表单的操作(添加与回显)之添加功能实现
- element ui实现多层级复杂表单的操作(添加与回显)之回显功能实现
实现效果图如下:
有些地方打码了,不过不影响整个效果的展示。这个写起来还是有点复杂的,尤其是在回显内容的时候,费了不少周折,下面来分享一下这块儿功能的实现。
实现思路
- 声明一个变量,用来存放采集数据的个数。
- 通过
v-for
循环,展示页面中有多少个采集数据的表单个数。 - 点击最下面新增的按钮时,会添加一个采集数据的表单,所以这块儿内容我们得动态操作,我这边的方法是,
v-model="xxx[index]"
的方式实现,index用来区分当前是第几个,在后面取值的时候也方便。 - 继续身边一个
formList
变量,作为下面表格的表单,也是根据元素个数来循环的 - 注意:凡是在循环中的,
v-model
都不可以一样,否则会造成数值错乱的情况(多个表单中的值一样)
实现展示多个采集数据表单
html
代码:
<div v-for="(item,index) in attribute" v-if="index < checkList.length"> <el-row :gutter="10" style="margin-top: 20px;"> <el-row> <el-col :span="12"><span style="font-size: 15px;font-weight: 600;margin: 5px 0 0 30px;">采集数据</span></el-col> </el-row> <el-row style="margin-top: 20px;"> <el-col :span="8"> <el-form-item label="采集数据类型:" prop="checkList" :rules="[ { required: true, message: '请选择采集数据类型', trigger: 'blur', }, ]"> <el-select v-model="deviceDataCheck[index]" @change="deviceDataCheckChange($event,[index])" placeholder="请选择采集数据类型"> <el-option v-for="item in checkList" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" ></el-option> </el-select> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="固定:" prop="" :rules="[ { required: false, message: '示例:100或者250', trigger: 'blur', }, ]"> <el-input-number style="width: 80%;" :min="1" v-model="samplingFrequency[index]" placeholder="示例:100" :step="1"></el-input-number> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="类别式:" prop="schemeOfDataSourceType" :rules="[ { required: true, message: '大于或等于1的整数', trigger: 'blur', }, ]"> <el-select v-model="schemeOfDataSourceType[index]" placeholder="请选择 类别描述方式"> <el-option v-for="item in schemeOfDataSourceTypeList" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" ></el-option> </el-select> </el-form-item> </el-col> </el-row> <el-row> <el-col :span="8"> <el-form-item label="数据元素个数:" prop="countOfCompound" :rules="[{ required: false, message: '大于或等于1的整数', trigger: 'blur',}]"> <el-input-number style="width: 80%;" :disabled="isCountOfComw[index]" :min="1" v-model="countOfCompound[index]" @change="handleChange($event,[index])" placeholder="示例:1" controls-position="right"></el-input-number> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="测量:" prop="measurePeriodExist" :rules="[ { required: true, message: '请选择', trigger: 'blur', }, ]" > <el-select v-model="measurePeriodst[index]" @change="forceUpdateChange" placeholder="请选择"> <el-option v-for="item in measurePeriod" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" ></el-option> </el-select> </el-form-item> </el-col> <el-col v-if="countOfCompound[index] != null" :span="24" style="margin-bottom: 30px"> <el-col :span="24" style="margin-bottom: 0px"> <el-col style="text-align: center;line-height: 40px;border: 1px solid #dcdfe6;margin-bottom: 0px;" :span="3">序号</el-col> <el-col style="text-align: center;line-height: 40px;border: 1px solid #dcdfe6;margin-bottom: 0px;":span="5">采集数据类型</el-col> <el-col style=" text-align: center; line-height: 40px; border: 1px solid #dcdfe6; margin-bottom: 0px; " :span="4">类别</el-col> <el-col style=" text-align: center; line-height: 40px; border: 1px solid #dcdfe6; margin-bottom: 0px; " :span="4" >单位</el-col > <el-col style=" text-align: center; line-height: 40px; border: 1px solid #dcdfe6; margin-bottom: 0px; " :span="3" >类型</el-col > <el-col style=" text-align: center; line-height: 40px; border: 1px solid #dcdfe6; margin-bottom: 0px; " :span="5" >类型</el-col > </el-col> <el-divider></el-divider> </div>
页面中有多少采集数据的表单取决于,点了多少下新增的按钮,默认只有一个,点一下新增按钮就多加一个 ,所以此时我们需要声明一个用来记录采集数据个数的变量。在data
中声明:
attribute: [1],
然后在method
中写新增的点击事件:
//新增采集数据属性按钮 addAttribute(){ //小于采集数据类型的话可以加 if(this.attribute.length<this.checkList.length){ this.attribute.push(this.attribute.length+1); } },
checkList
的值是采集数据类型的下拉,先声明在使用,代码如下:
checkList: [],
mounted
中构造checkList
集合:
//采集数据类型 getDictionary({ code: "deviceData" }).then((res) => { this.checkList = res.data.data; let arr = []; for(let i = 0; i < this.checkList.length; i++) { arr[i] = true; } this.isCountOfCompoundShow = [arr]; });
注意此处加了个判断,当时考虑的是,采集数据不可以无限新增,取决于采集数据下面的采集数据类型下拉,下拉中有多少个值,就可以新加多少个,为了直观展示,可以看看下面的图:
现在我们就实现了,点击新增按钮时,动态的添加一个采集数据表单,默认之后一个,最多只能添加采集数据类型下拉框中的个数。
根据元素个数,动态生成表格
因为下面表格中的行数是由上面元素个数来决定的,所以需要编写元素个数数字表单的改变事件。此处还有个地方需要验证,即上面采集数据类型如果不写的话,下面元素个数是禁用状态,无法操作。
html
代码
<el-row> <el-col :span="8"> <el-form-item label="数据元素个数:" prop="countOfCompound" :rules="[{ required: false, message: '大于或等于1的整数', trigger: 'blur',}]"> <el-input-number style="width: 80%;" :disabled="isCountOfCompoundShow[index]" :min="1" v-model="countOfCompound[index]" @change="handleChange($event,[index])" placeholder="示例:1" controls-position="right"></el-input-number> </el-form-item> </el-col> <el-col :span="8"> <el-form-item label="测:" prop="measurePeriodExist" :rules="[ { required: true, message: '请选择是', trigger: 'blur', }, ]" > <el-select v-model="measurePeriodExist[index]" @change="forceUpdateChange" placeholder="请选择"> <el-option v-for="item in measurePeriodExistList" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" ></el-option> </el-select> </el-form-item> </el-col> <el-col v-if="countOfCompound[index] != null" :span="24" style="margin-bottom: 30px"> <el-col :span="24" style="margin-bottom: 0px"> <el-col style="text-align: center;line-height: 40px;border: 1px solid #dcdfe6;margin-bottom: 0px;" :span="3">序号</el-col> <el-col style="text-align: center;line-height: 40px;border: 1px solid #dcdfe6;margin-bottom: 0px;":span="5">采集数据类型</el-col> <el-col style=" text-align: center; line-height: 40px; border: 1px solid #dcdfe6; margin-bottom: 0px; " :span="4">数据源各元素类别</el-col> <el-col style=" text-align: center; line-height: 40px; border: 1px solid #dcdfe6; margin-bottom: 0px; " :span="4" >数值单位</el-col > <el-col style=" text-align: center; line-height: 40px; border: 1px solid #dcdfe6; margin-bottom: 0px; " :span="3" >数据类型</el-col > <el-col style=" text-align: center; line-height: 40px; border: 1px solid #dcdfe6; margin-bottom: 0px; " :span="5" >度量属性类型</el-col > </el-col> <!--表格--> <el-col v-for="(items, indexL) in formList[index]" :key="indexL" :span="24" style="margin-bottom: 0px; height: 40px"> <!-- 序号 --> <el-col style=" text-align: center; line-height: 40px; border: 1px solid #dcdfe6; margin-bottom: 0px; height: 40px; " :span="3">{{ indexL + 1 }}</el-col> <!-- 采集数据类型 --> <el-col style=" text-align: center; line-height: 40px; border: 1px solid #dcdfe6; margin-bottom: 0px; height: 40px; " :span="5"><span v-if="deviceDataCheck[index] == 'hr'">心率</span><span v-if="deviceDataCheck[index] == 'rri'">RRI</span></el-col> <!-- 数据源各元素类别 --> <el-col style="text-align: center;line-height: 40px;border: 1px solid #dcdfe6;margin-bottom: 0px;height: 40px;" :span="4"> <el-form-item prop="dataSourceType" :rules="[ { required: true, message: '请选择数据源类别', trigger: 'blur', }, ]" label-width="0px"> <el-select v-model="items.dataSourceType" @change="forceUpdateChange" style="width: 100%" placeholder="请选择数据源各元素类别"> <el-option v-for="item in dataSourceTypeList" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey"></el-option> </el-select> </el-form-item> </el-col> <!-- 数值单位 --> <el-col style=" text-align: center; line-height: 40px; border: 1px solid #dcdfe6; margin-bottom: 0px; height: 40px; " :span="4"> <el-form-item prop="unitCode" :rules="[ { required: true, message: '请选择数值单位', trigger: 'blur', }, ]" label-width="0px" > <el-select v-model="items.unitCode" @change="forceUpdateChange" style="width: 100%" placeholder="请选择 数值单位" > <el-option v-for="item in unitCodeList" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" ></el-option> </el-select> </el-form-item> </el-col> <!-- 数据类型 --> <el-col style=" text-align: center; line-height: 40px; border: 1px solid #dcdfe6; margin-bottom: 0px; height: 40px; " :span="3"> <el-form-item prop="dataType" :rules="[ { required: true, message: '请选择采集数据类型', trigger: 'blur', }, ]" label-width="0px" > <el-select v-model="items.dataType" @change="forceUpdateChange" style="width: 100%" placeholder="请选择 数据类型" > <el-option v-for="item in dataTypeList" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" ></el-option> </el-select> </el-form-item> </el-col> <!-- 度量属性类型 --> <el-col style=" text-align: center; line-height: 40px; border: 1px solid #dcdfe6; margin-bottom: 0px; height: 40px; " :span="5"> <el-form-item prop="metricSpec" :rules="[ { required: true, message: '请选择度量属性类型', trigger: 'blur', }, ]" label-width="0px" > <el-select v-model="items.metricSpec" @change="forceUpdateChange" style="width: 100%" placeholder="请选择 度量属性类型" > <el-option v-for="item in metricSpecList" :key="item.dictKey" :label="item.dictValue" :value="item.dictKey" ></el-option> </el-select> </el-form-item> </el-col> </el-col> </el-col> </el-row>
接下来就是元素个数数字表单的改变事件:
//元素个数的改变事件 handleChange(value,index) { this.formList[index] = []; let num = this.formList[index].length; for (let i = 0; i < value - num; i++) { this.formList[index].push({ dataSourceType: "", unitCode: "", dataType: "", metricSpec: "", //checkType: this.checkList[0].dictValue, }); } },
以上内容即可实现静态页面表单的交互。