做项目时遇到这样一个需求:保函类型是多选,调后台接口循环出来。每个保函类型后面都有保函比例(输入框)和有效期(日期选择器),并且填写对应的信息。如果没有选中保函类型,保函比例和有效期禁用。当勾选中某个保函类型的时候,其后面的保函比例和有效期就可用。回显的时候同样效果。
红色框中是保函类型,绿色框是每一条保函完整的信息,包括保函类型,保函比例,有效期。效果图如下
首先下面是html代码
<el-row :gutter="10">
<el-form size="small" :label-position="label-position">
<el-col :span="5">
<el-form-item label-width="0">
<el-checkbox-group v-model="checkGuarantee" @change="checks">
<el-checkbox
v-model="item.dictId"
v-for="(item, index) in checkGuarantees"
:label="item.dictName"
:key="index">
{{item.dictName}}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item v-for="(item, index) in checkGuarantees" :key="index" label="保函比例" label-width="80px">
<el-input @change="gurranteeRate" v-model.trim="item.valueInput" :disabled="disableds[index]"></el-input>
</el-form-item>
</el-col>
<el-col :span="9">
<el-form-item v-for="(item, index) in checkGuarantees" :key="index" label="有效期" label-width="120px">
<el-date-picker v-model="item.valueDate" :disabled="disableds[index]" value-format="yyyy-MM-dd" type="date" placeholder="选择日期"></el-date-picker>
</el-form-item>
</el-col>
</el-form>
</el-row>
data中定义的数据如下
data() {
return {
disableds: [], //保函比例及有效期是否禁用数组
checkGuarantees: [], //要循环的保函类型(从后台获取的数据)
checkGuarantee: [], //选中的保函类型
payGuarantees: [] //选好保函后发送请求时需要的参数
}
}
1,因为保函比例和有效期是根据保函类型来动态生成的,即有多少种保函类型,就会生成多少个保函比例及有效期输入框,所以循环的时候绑定的是保函类型的数据checkGuarantees。
checkGuarantees的数据如下:
[{
dictName: "预付款保函",
dictId: "0234637856666576"
},
{
dictName: "履约保函",
dictId: "579832512439851"
},
{
dictName: "质量保函",
dictId: "076632453263252"
}]
2,页面初始化的时候,调接口得到checkGuarantees,循环出保函类型。保函类型多选框选中的值是保函类型的label,里面没有保函比例和有效期,所以往保函对象里添加保函比例和有效期字段。同时输入框和日期选择器
(后面全简称为输入框)是否禁用,刚开始全设置为不可用状态。代码如下
// 进入页面时,首先将所有的保函类型展示出来 调接口获取数据
const guaranteeType = { dictTypeCode: "CONTRACT_TYPE" }; //请求参数
contractAddApi.getDict(guaranteeType) //发送请求
.then((res) => {
const datas = res.data; // 后台返回的数据
for (var i = 0; i < datas.length; i++) {
// 这里是初始化往保函类型对象中添加保函比例和有效期以及id字段,并且将它们放在同一个对象里面
let item = {
dictName: datas[i].dictName,
dictId: datas[i].dictId,
valueInput: "", //保函比例绑定的值
valueDate: "" //有效期绑定值
};
//将添加完的对象添加到checkGuarantees数组中去
this.checkGuarantees.push(item);
}
// 初始的时候让所有的输入框禁用
for (var i = 0; i < this.checkGuarantees.length; i++) {
this.disableds.push(true);
}
})
.catch((error) => {
});
此时就会得到如下效果
3,保函类型的change事件,当选中某个保函的时候其后面的输入框可用状态。代码如下
checks(val) {
this.disableds = [];
this.checkGuarantees.forEach((v, i) => {
this.disableds.push(true);
this.checkGuarantee.forEach((_v, _i) => {
if (v.dictName == _v) {
this.disableds[i] = false;
}
})
});
}
选好保函类型,填写完其后面的保函比例和有效期后得到checkGuarantees的数据如下
[{
dictName: "预付款保函",
dictId: "0234637856666576"
},
{
dictName: "履约保函",
dictId: "579832512439851"
},
{
dictName: "质量保函",
dictId: "076632453263252"
}]
[{
dictName: "预付款保函",
dictId: "0234637856666576",
valueInput: "1",
valueDate: "2018-12-25"
},
{
dictName: "履约保函",
dictId: "579832512439851",
valueInput: "",
valueDate: null
},
{
dictName: "质量保函",
dictId: "076632453263252",
valueInput: "3",
valueDate: "2019-01-05"
}]
5,将选中的checkGuarantee多选框数据以及填写完信息后的checkGuarantees数据(包括选中以及没选中的所有信息)循环,将checkGuarantee中的数据(即选中的数据)与checkGuarantees中的dictName相比较,如果相等说明这条保函被选中了,就push到payGuarantees,循环完后就可以得到要发给后台的数据了。payGuarantees最终的数据如下
[{
dictName: "预付款保函",
dictId: "0234637856666576",
valueInput: "1",
valueDate: "2018-12-25"
},
{
dictName: "质量保函",
dictId: "076632453263252",
valueInput: "3",
valueDate: "2019-01-05"
}]
6,数据回显,将后台返回的数据payGuarantees以及checkGuarantees循环比较出保函类型相同的项,将其push到多选框绑定的值checkGuarantee中,这样多选框选中状态就会回显。然后将其对应的保函比例和有效期赋值给checkGuarantees中对应条的保函信息,这样填写的保函比例和有效期就能显示出来了。最后将checkGuarantees再循环一次,显示输入框是否禁用的状态。代码如下
// 数据回显 data.payGuarantees后台返回的数据(保函类型,保函比例,有效期)
data.payGuarantees.forEach((v, i) => {
this.checkGuarantees.forEach((_v, _i) => {
if (v.dictName == _v.dictName) {
this.checkGuarantee.push(v.dictName);
_v.valueInput = v.valueInput;
_v.valueDate = v.valueDate;
_v.dictId = v.dictId;
}
})
})
// 再将输入框和日期选择器是否禁用循环一次
this.disableds = [];
this.checkGuarantees.forEach((v, i) => {
this.disableds.push(true);
this.checkGuarantee((_v, _i) => {
if (v.dictName == _v) {
this.disableds[i] = false;
}
})
})
以上就是我实现根据多选框动态生成输入框,并且将其回显的做法。方法虽笨,但还是有用的。如果小伙伴们发现更好的方法或者可以优化的地方,看在我这么可爱的份儿上告诉我一下吧