实现的思路
将所有勾选的数据的id放到一个数组(selectIdAll)中,每次翻页获取当前页面的数据(tableData)后,循环二者进行对比,如果tableData中的某些数据的id和selectIdAll中的数据相等,则给tableData的这些相等的数据加一个属性_check=true,不相等的设置_check=false。
用到vue-easytable的方法
当操作多选框时,vue-easytable提供了三个事件,分别是:
我们用select-all(全选时触发)和select-change(单选时触发)即可。
详细步骤(思路)
结合vue-easytable提供的方法,有3个比较重要的步骤+1
- 一个一个选择时,循环所有选中项的数组(即:selectIdAll),判断该数组中有没有当前的项,有则splice,没有则push。
- 全选时,找到当前页和所有选中项不同的数据,循环这些数据,让每一条数据都走一遍步骤1中的方法,将这些数据添加到selectIdAll中;
- 全部取消时,找到当前页和所有选中项相同的数据,循环这些数据,每一条都走一遍步骤1中方法,将这些数据剔除。
- 每次加载当前页的数据时,将当前页的数据和selectIdAll进行对比,有则添加属性_checked = true,没有则_checked = false。
重要步骤的代码
- 单选
// 单选
selectSingleChange(selection,rowData) {
this.compareCheckedData(id, this.selectIdAll);
},
- 全选
selectTableData(selection) {
if (selection.length > 0) {
// 全部选择
let arr1 = this.getArrDifference(this.tableDataid, this.selectIdAll);
arr1.forEach(item => {
this.compareCheckedData(item, this.selectIdAll)
})
} else {
// 取消全选
let arr2 = this.getArrEqual(this.tableDataid, this.selectIdAll);
arr2.forEach(item => {
this.compareCheckedData(item, this.selectIdAll)
})
}
},
- 加载完当前页数据后进行处理该页的数据
this.tableData.map((tableitem, index) => {
tableitem._checked = false; //先设置所有的状态为不勾选
this.selectIdAll.map((smallitem, index1) => { //再判断有相同项的状态为勾选
if (tableitem.assetsid == smallitem) {
tableitem._checked = true;
}
})
return tableitem;
})
- 公共方法1,有就删除,没有就追加
compareCheckedData(id, arr) {
var data_index = arr.indexOf(id);
if (data_index > -1) {
arr.splice(data_index, 1);
} else {
arr.push(assetsid);
}
return arr
},
- 公共方法2,两个数组对比取arr1中在arr2中存在的值(普通数组,不适用于对象数组)
// 对比取相同值
getArrEqual(arr1, arr2) {
let newArr = [];
for (let i = 0; i < arr2.length; i++) {
for (let j = 0; j < arr1.length; j++) {
if (arr1[j] === arr2[i]) {
newArr.push(arr1[j]);
}
}
}
return newArr;
},
- 公共方法3,两个数组对比取arr1中在arr2中不存在的值(普通数组,不适用于对象数组)
getArrDifference(arr1, arr2) {
let newArr = [];
if (arr2.length == 0) {
return arr1
} else {
for (let i = 0; i < arr1.length; i++) {
if (arr2.indexOf(arr1[i]) < 0) {
newArr.push(arr1[i])
}
}
}
return newArr;
},
补充
以上这些处理,最后得到的是选中项id组成的数组。但是我的页面业务其他逻辑是需要这些id所在的对象所组成的数组。
为了得到这个对象所在的数组我用了三个方法,分享一下:
- 从最开始的方法开始改造,如:compareCheckedData这个方法,由传进去id变为直接传对象,但是会发现对象数组和普通数组的处理方式区别很大,或者说普通数组有的方法对象数组没有,即使有兼容性也很差,比如indexOf在对象数组中就用不了,findIndex可以用,但是ie11以下不兼容,…,尝试了很多,最终这种想法放弃了。
- 让后台协助处理,我传给他所有的id,他返回给我这些id对应的对象所组成数组(这种方式最low)。
- 每加载一页的数据,将这些数据追加起来放到一个数组tablePageAll中,在watch中监听selectIdAll,去重tablePageAll的数据,循环tablePageAll数组和selectIdAll,如果item.id==id,就push到一个空数组中。reduce() 用于对象数组的去重,很棒。 推荐使用
watch:{
selectIdAll(n) {
let obj = {};
let newArr = [];
//tableDataClickAllPage 为点击不同页数所加载的数据的所有的数组
this.tableDataClickAllPage = this.tableDataClickAllPage.reduce((cur, next) => {
obj[next.id] ? "" : obj[next.id] = true && cur.push(next);
return cur;
}, []) //设置cur默认类型为数组,并且初始值为空的数组
for(let i =0;i<this.tableDataClickAllPage.length;i++){
let wrap = this.tableDataClickAllPage[i];
for(let j =0;j<n.length;j++){
let inner = n[j];
if(wrap.id == inner){
newArr.push(wrap);
}
}
}
this.selectDataAll = newArr;
}
}