前言
通过计算属性return的值可以保证相对独立,又可以在其依赖的属性的值发生变化时进行重新计算。
实现逻辑
具体的实现逻辑我写在了代码的注释里了,这里就写下核心的逻辑)
1.保证每个下拉框的Option循环的investorList都是独立的,不会影响到其他的下拉框
2.把所有Select已经选中的选项放入一个数组arr中
3.所有的Option的显示数据investorList,需要保留当前自己Select选中的选项,再去除在arr中已经有的选项
核心代码
1.结构
代码如下(示例):
<el-table
:data="contractData.signInvestors"
border
>
<el-table-column label="公司名称" align="center">
<template scope="props">
<el-col :span="17">
<el-select
v-model="props.row.investorName"
filterable
remote
placeholder="请输入关键词"
:remote-method="querySearchInvestor"
:loading="loading4"
@change="
(value) =>
handleSelectInvestor(value, 2, props.$index)
"
>
<el-option
v-for="item in investorList"
:key="item.ou"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-col>
<el-col class="line" :span="2">-</el-col>
<el-col :span="5">
<el-input v-model="props.row.ou" readonly></el-input>
</el-col>
</template>
</el-table-column>
<el-table-column label="操作" width="100" align="center">
<template scope="props">
<el-button
type="text"
size="small"
@click="editSignInvestors(1, props.$index)"
>增加</el-button
>
<el-button
type="text"
size="small"
@click="editSignInvestors(2, props.$index)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
2.数据
data() {
return {
signInvestors: [{ investorName: "", ou: "" }],
investorList: []
};
},
3.方法
methods: {
// 增加或删除签约主体
editSignInvestors(type, index) {
if (type === 1) {
this.contractData.signInvestors.push({
investorName: "",
ou: "",
});
} else {
if (this.contractData.signInvestors.length === 1) {
this.$alert("不能再删除啦!", "提示", {
confirmButtonText: "确定",
type: "info",
});
} else {
this.contractData.signInvestors.splice(index, 1);
}
}
},
}
4.计算属性
computed: {
showInvestorList() {
return (val) => {
//将option的显示数据进行深拷贝
let newList = JSON.parse(JSON.stringify(this.investorList));
//处理signInvestors数据,返回一个新数组arr
//arr数组就相当于所有Select选中的数据集合(没有选中的为'',不影响判断),只要在这个集合里面,其他的下拉框就不应该有这个选项
const arr = this.contractData.signInvestors.map((item) => {
//将其格式{value:'NewYork'}变成['NewYork'],方便使用indexOf进行判断
return (item = item.investorName);
});
//过滤出newList里面需要显示的数据
newList = newList.filter((item) => {
//当前下拉框的选中的数据需要显示
//val就是当前下拉框选中的值
if (val == item.investorName) {
return item;
} else {
//再判断在arr这个数组中是不是有这个数据,如果不在,说明是需要显示的
if (arr.indexOf(item.investorName) == -1) {
return item;
}
}
});
//返回Options显示数据
return newList;
};
},
}
在整个showInvestorList中,唯一的变量就是signInvestors,只要signInvestors的值有改变,就会触发计算属性的重新计算,这样就可以保证无论是Select选中某个选项,还是增加下拉框,或者删除下拉框都会让每个下拉框对应的Option中的newList进行重新生成,从而达到多个select不能重复选择相同数据的功能。
总结
感觉计算属性用来写这个功能还是挺方便的,希望以后能挖掘计算属性的更多潜能。