首先我的页面的需求是,一个el-table,可以分页,然后右边是自己写的一个选中的所有的数据展示,点击右边的删除按钮,可以删除选中的一条数据,并且在表格中删除选择的状态。我的这个需求死右侧选中的数据只能一条一条的删除,但表格中可以全选和取消全选。以下提供表格能全选和不能全选的方法。
遇到的问题:
因为我右边展示的数据的字段和左侧表格的字段不一致,所以每次点击删除另一页数据的时候就会默认的在右侧有新增一条,并且使用selection-change的方法的时候,返回的数组总数成倍增加。
解决方法:
方法一:
表格不能全选
如果不涉及全选的情况,可以使用select方法,每次一选择的时候就判断右侧的展示数组中是否有这一条数据,若有,则删除,若没有则增加。具体实现代码如下:
下面展示一些 内联代码片
。
//rightArr右侧的展示数组, select方法中的代码
let objIndex = this.rightArr.findIndex(
(item) => item.id === row.enpId
);
if (objIndex != -1) {
this.rightArr.splice(objIndex, 1);
} else {
let obj = {
name: row.companyName,
pname: row.orgName,
id: row.enpId,
};
this.rightArr.unshift(obj);
}
//请求接口成功后的代码:treeList 左侧表格的数据,如要回显也是同样的实现
this.treeList = res.data.records || [];
this.pageInfo.total = Number(res.data.total);
this.$refs.multipleTable.clearSelection() //这一步非常重要
if (this.rightArr.length > 0) {
this.$nextTick(() => {
this.treeList.forEach((item) => {
let obj = this.rightArr.find((val) => val.id === item.enpId);
if (obj) {
this.$refs.multipleTable.toggleRowSelection(item, true);
}
});
});
}
//右侧点击删除时的方法:
let templateIndex = this.treeList.findIndex(item => item.enpId == info.id)
if(templateIndex != -1) {
this.$refs.multipleTable.toggleRowSelection(this.treeList[templateIndex]);
} // 如果在删除的数据在当前页,那么直接改变他的选中状态,因为使用这个方法改变选中状态,并不会出发select方法,所以需要自己手动删除右侧选中的数据
this.rightArr.splice(index, 1); //删除右侧的选择的那一条数据
方法二:
表格能够全选
假如需求是表格能够全选,那么上面的方法就不适用,因为点击全选的那个框,同样也出发不了select这个方法,那么之前说的遇到的问题就出现了,该怎样解决呢。后来我发现,因为我给右侧的数组有使用map,所以点击右侧的删除之后,在表格selection-change方法就有一点儿识别不清楚当前的操作,就会重复的增加当前页面的选中的数组。导致直接使用this.$refs.multipleTable.toggleRowSelection(row)表格就不能取消选中的状态。不知道能不能看懂我说的,没事,我自己应该能懂。话不多说,上我自己后来解决好的代码:
// 前提条件:el-table需要增加 :row-key="getRowKeys" type="selection"的列中加 :reserve-selection="true"
getRowKeys方法:
getRowKeys(row) {
// console.log("🚀 ~ getRowKeys ~ row:", row);
return row.enpId; // id是表格数据的唯一标识字段
},
// 请求接口成功后的部分代码:
if (this.rightArr.length > 0) {
this.$nextTick(() => {
this.treeList.forEach((item) => {
let obj = this.rightArr.find((val) => val.enpId === item.enpId);
if (obj) {
this.$refs.multipleTable.toggleRowSelection(item, true);
} else {
this.$refs.multipleTable.toggleRowSelection(item, false);
}
});
});
}
假如需要回显:在回显请求的接口中的部分代码
const arr = res.data.enps
this.rightArr = [...arr];
this.oldSelectData = JSON.parse(JSON.stringify(this.rightArr)); //这个数组非常重要,因为我不知道是不是我哪儿写着有问题,后面需要回显的时候,改变的都会是这个数组
if (this.rightArr.length > 0) {
console.log("🚀 ~ .then ~ this.rightArr:", this.rightArr);
this.$nextTick(() => {
this.treeList.forEach((item) => {
let obj = this.rightArr.find((val) => val.id === item.enpId);
if (obj) {
this.$refs.multipleTable.toggleRowSelection(item, true);
} else {
this.$refs.multipleTable.toggleRowSelection(item, false);
}
});
});
}
//selection-change方法,对了,还有一个是否点击了下方表格的字段clicked

上面是我表格绑定的方法
handleSelectionChange(data) {
if (!this.edit) { // 判断是否编辑修改
if (data.length > 0) {
this.rightArr = data.map((row) => {
return {
orgName: row.companyName,
pname: row.orgName,
enpId: row.enpId,
};
});
} else {
this.rightArr = [];
}
} else {
this.rightArr = this.oldSelectData;
}
},
handleAelectAll(data) {
this.clicked = true;
if (data.length > 0) {
data.forEach((row) => {
let objIndex = this.rightArr.findIndex(
(item) => item.enpId === row.enpId
);
if (objIndex == -1) {
let obj = {
orgName: row.companyName,
pname: row.orgName,
enpId: row.enpId,
};
this.rightArr.unshift(obj);
}
});
}
},
handleSelect(date, row) {
this.clicked = true;
if (this.edit) {
let objIndex = this.oldSelectData.findIndex((i) => i.id === row.enpId);
if (objIndex != -1) {
this.oldSelectData.splice(objIndex, 1);
} else {
let obj = {
orgName: row.companyName,
pname: row.orgName,
enpId: row.enpId,
id: row.enpId,
};
this.oldSelectData.unshift(obj);
}
}
},
点击右侧的删除时候的方法:
handleDelete(info, index) {
if (!this.edit) {
let templateIndex = this.treeList.findIndex(
(el) => el.enpId == info.enpId
);
console.log("🚀 ~ handleDelete ~ templateIndex:", templateIndex);
if (templateIndex != -1) {
this.$refs.multipleTable.toggleRowSelection(
this.treeList.find((el) => el.enpId == info.enpId),
false
); //注意注意: 在新增的情况下,如果使用了map修改了右侧数据的,这儿这个false非常关键,明确的告诉左侧的表格,取消这条数据的选中状态,不明确的增加false的话就会出现问题,而且当前页面能够找到删除的这条数据的时候,改变了他的数据状态,会自动触发select-change这个方法,所以就不能再手动删除右侧选择的数据了,没有在当前表格页找到,才需要手动删除
} else {
this.rightArr.splice(index, 1);
}
if (this.rightArr.length > 0) { // 通过右侧的数据来为左侧的表格增加每条数据的选中的状态
this.$nextTick(() => {
this.rightArr.forEach((item) => {
let obj = this.treeList.find((el) => el.enpId == item.enpId);
if (obj) {
this.$refs.multipleTable.toggleRowSelection(obj, true);
}
});
});
}
} else { // 在修改状态下:
let templateIndex = this.treeList.findIndex(
(el) => el.enpId == info.enpId
);
console.log("🚀 ~ handleDelete ~ 222222templateIndex:", templateIndex);
if (templateIndex != -1) {
this.$refs.multipleTable.toggleRowSelection(
this.treeList.find((el) => el.enpId == info.enpId),
false
); // 这儿的false也是必须要加的,和新增不同的是这儿无论在当前也是否找到删除的那条数据,都必须在oldSelectData的这个数组中删除这条数据
let objIndex = this.oldSelectData.findIndex(
(i) => i.id === info.enpId
);
this.oldSelectData.splice(objIndex, 1);
console.log(
"🚀 ~ handleDelete ~ this.oldSelectData:",
this.oldSelectData
);
} else {
this.oldSelectData.splice(index, 1);
}
if (this.oldSelectData.length > 0) { // 通过oldSelectData这个数组里面的数据来反选表格的选择状态
this.$nextTick(() => {
this.oldSelectData.forEach((item) => {
let obj = this.treeList.find((el) => el.enpId == item.enpId);
if (obj) {
this.$refs.multipleTable.toggleRowSelection(obj, true);
}
});
});
}
}
// }
},
//template里面的右侧的代码
<div class="users_select users_item">
<div class="total_info">
<p>
已选<span class="bold">{{
!edit ? rightArr.length : oldSelectData.length
}}</span
>个企业
</p>
</div>
<div class="users" v-loading="rightLoading" v-if="!edit">
<div
class="right_user"
v-for="(item, index) in rightArr"
:key="index"
>
<div class="users_select_content">
<div class="users_select_left">
<p class="left_name">{{ item.name}}</p>
</div>
<div
v-if="type !== 'view'"
class="users_select_right"
@click="handleDelete(item, index)"
>
<i class="el-icon-error"></i>
</div>
</div>
<div class="users_select_desc">
<p class="desc_item desc_item_left">
{{ item.pname }}
</p>
</div>
</div>
</div>
<div class="users" v-loading="rightLoading" v-else>
<div
class="right_user"
v-for="(item, index) in oldSelectData"
:key="index"
>
<div class="users_select_content">
<div class="users_select_left">
<p class="left_name">{{ item.name}}</p>
</div>
<div
v-if="type !== 'view'"
class="users_select_right"
@click="handleDelete(item, index)"
>
<i class="el-icon-error"></i>
</div>
</div>
<div class="users_select_desc">
<p class="desc_item desc_item_left">
{{ item.pname }}
</p>
</div>
</div>
</div>
</div>
// watch监听
watch: {
value: {
handler(val) { // 当新增或者编辑弹窗展示的时候才开始调用方法
if (val) {
this.treeList = [];
this.getEnpTable(); // 表格的数据请求
if (this.info) { // 如果传入了info,则表示是编辑
this.getOldData(); // 需要回显的选中数据请求
this.clicked = false;
this.edit = true;
}
}
},
immediate: true,
},
},