在项目之中我们肯定都有碰到过这样的一个需求,分页渲染后端的数据后,要对这些数据进行批量处理,比如说:批量删除功能,那就拿这个例子来说一下跨页的多选和全选如何实现。
首先我们要了解后端所需要的数据是什么,批量删除后端需要的是每一个选中对象的id所组成的数组,我们看到这个首先想到的就是先new一个空数组,当点击一个元素时,将该元素的id添加到这个空数组之中,这个时候只需要判断new出来的这个数组是否包含该元素的id来点亮这个元素。当这一页的所有元素都被选中的时候,就要点亮全选按钮。
批量选中和取消:
// 判断是否全选
isContained(a, b) {
// 如果a的长度小于b那么b中肯定没有被全部选中,直接false
if (a.length < b.length) return false;
for (let i = 0; i < b.length; i++) {
// 遍历b中的元素,判断b中是否有元素存在于a中,有不存在的直接false
//
if (!a.includes(b[i].id)) return false;
}
// 遍历结束,返回true
return true;
},
// 批量选中
selectDel(val) {
this.dels.push(val.id);
//调用封装的函数给c赋值,用c来判断是否全选
let c = this.isContained(this.dels, this.cellectGoodsList);
this.all = c;
},
// 取消勾选
deselect(item) {
let i = this.dels.indexOf(item.id);
if (i > -1) {
this.dels.splice(i, 1);
}
//依然要判断是否全选
let c = this.isContained(this.dels, this.cellectGoodsList);
this.all = c;
},
全部选中和取消全选
// 全选
allChoose() {
this.cellectGoodsList.forEach(item => {
if (!this.dels.includes(item.id)) {
this.dels.push(item.id);
}
});
let c = this.isContained(this.dels, this.cellectGoodsList);
this.all = c;
},
// 取消全选
cancelChoose() {
let id = "";
//cellectGoodsList为渲染页面数据的数组
//遍历该数组,判断id是否包含在添加的数组中,如果有,删除这个id
this.cellectGoodsList.forEach(item => {
id = this.dels.indexOf(item.id);
if (id > -1) {
this.dels.splice(id, 1);
}
});
let c = this.isContained(this.dels, this.cellectGoodsList);
this.all = c;
},
html部分判断
<div class="choose-left" @click="cancelChoose" v-if="all">
<!--全选-->
<img src="../assets/imgs/again.png" alt="" />
</div>
<div class="choose-left" v-else @click="allChoose">
<!--未全选-->
<img src="../assets/imgs/noAgain.png" alt="" />
</div>
<span class="choose-right">全选</span>
<!--选中,点击取消-->
<img class="messageItem" src="../assets/imgs/again.png" v-if="dels.includes(item.id)" @click="deselect(item)" />
<!--未选中,点击选中-->
<img class="messageItem" src="../assets/imgs/check.png" v-else @click="selectDel(item)" />
但是这个方式有些浪费性能,因为在每次点击选中取消的时候,都需要进行遍历来判断,如果有更好的方法,欢迎点评。