不仅是单页选择,想对整个列表项进行操作?实现列表跨页复选

340 阅读3分钟

前言

最近后管项目新加了一个需求,需要在原有的列表上加一个全选按钮,实现对整个列表或者筛选后的整个列表数据进行一个整体的操作。

看了下Element中的el-table文档,并没有现成的API,只好自己实现。

大概的思路就是切换页面时将当前页面的数据勾选中(当然其中也踩了几个坑🕳,捋清思路实现起来其实也很简单( •̀ ω •́ )y)。

1. 添加一个跨页全选按钮

  • 绑定跨页数组state.pageChecked
  • 绑定跨页全选方法checkAll
            <el-checkbox 
                v-model="state.pageChecked" 
                label="全选" 
                @change="checkAll" 
                :disabled="!state.total" />

image.png

2.table设置如下

  • 在el-table中添加
    • 表格内全选:@select-all="selectAll"
    • 表格内行勾选:@select="changeSelect"
    • 指定唯一标识符为row.id::row-key="getRowKeys"
  • 在el-table-column中添加
    • 设置为勾选项:type="selection"
    • :reserve-selection="true" : 当数据发生变化时,保留之前的选择状态,即使数据重新加载或分页切换,已选中的行仍然会被记住,需要table配合使用:row-key来指定唯一标识符
        <el-table 
            v-loading="state.loading" 
            :data="state.tableData" 
            @select-all="selectAll"
            @select="changeSelect" 
            ref="tableRef" 
            :row-key="getRowKeys">
          <el-table-column type="selection" width="55" :reserve-selection="true" />
        </el-table>

3.调用接口获取数据

  • 实现跨页全选其实就是切换页面时将当前页面的数据勾选中
  • 选中的是当前页的数据,但是需要先判断当前页的每一行是否都存在跨页全选的数组中(state.tableData永远都是当前页全部数据,但state.saveCheckList可能在某一页不是全选,以state.saveCheckList为准来勾选)
const getTableData = () => {
  state.loading = true;
  student_list(query)
    .then(res => {
      if (res.code == 200 && res.data) {
        let result = res.data || [];
        state.tableData = result;
        state.tableData.forEach((row) => {
          let findex = state.saveCheckList.findIndex((item) => {
            return item.id == row.id;
          });
          if (findex >= 0) {
            tableRef.value.toggleRowSelection(row, true);
          }
        });
        state.total = res.total;
      }
    })
    .finally(() => {
      state.loading = false;
    });
};

4.当前行勾选或取消(changeSelect)

  • 全选用push加入
  • 反选用splice删除

image.png

const changeSelect = (selection, row) => {
  console.log('tableChangeSelect',row);

  let fitemIndex = state.saveCheckList.findIndex((item) => {
    return item.id == row.id;
  });

  if (fitemIndex < 0) {
    state.saveCheckList.push(row);
  } else {
    state.saveCheckList.splice(fitemIndex, 1);
  }
  if (state.saveCheckList.length === state.total) {
    state.pageChecked = true
  } else {
    state.pageChecked = false
  }
}

5.表格内全选(selectAll)

  • 反选
    • 每次点击切换分页,都会触发接口获取当前页的10条数据,并赋值给state.tableData
    • 当跨页全选时,在某一页点击取消全选当前页,需要把当前页的数据在跨页全选的数据中去除
  • 全选
    • 当跨页全选时,在某一页点击取消全选当前页再点击全选当前页,需要把当前页的数据在跨页全选的数据中加上
  • 如果跨页数组的长度等于列表全部数量,勾选跨页选中,否则取消
const selectAll = (val) => {
  if (val && val.length == 0) {
    console.log(val.length);
    state.tableData.forEach((row) => {
      let fitemIndex = state.saveCheckList.findIndex((item) => {
        return item.id == row.id;
      });
      if (fitemIndex >= 0) {
        state.saveCheckList.splice(fitemIndex, 1);
      }
    });
  } else if (val && val.length != 0 ) {
    val.forEach((row) => {
      let fitemIndex = state.saveCheckList.findIndex((item) => {
        return item.id == row.id;
      });
      if (fitemIndex < 0) {
        state.saveCheckList.push(row);
      }
    });
  }
  if (state.saveCheckList.length === state.total) {
    state.pageChecked = true
  } else {
    state.pageChecked = false
  }
}

6.跨页全选(checkAll)

  • 全选
    • 跨页全选使用总数量调接口赋值给跨页数组
    • 使用toggleAllSelection()将当前页全选
  • 反选
    • 将跨页数组清空
    • 使用clearSelection()取消当前页全选
const checkAll = (selection, row) => {
  state.loading = true
  if (state.pageChecked) {
    student_list({ ...query, size: state.total, page: 1 }).then((res) => {
      if (res.code == 200 && res.data) {
        state.saveCheckList = res.data;
        tableRef.value.clearSelection();
        tableRef.value.toggleAllSelection();
        state.loading = false
      }
    });
  } else {
    state.saveCheckList = [];
    tableRef.value.clearSelection();
    state.loading = false
  }
}

至此,已经完成了基于el-table实现跨页全选反选,以及保留el-table原有的单项复选和整页全选反选。

ps:因为每次点击跨页全选反选都会触发接口查询数据,如果table数据较大且接口较慢,会出现列表回显缓慢的情况,建议添加loading和disabled效果,防止频繁点击和列表卡顿

dacd2633d04544dabaac13d20e4eb0ef~tplv-73owjymdk6-jj-mark-v1_0_0_0_0_5o6Y6YeR5oqA5pyv56S-5Yy6IEAg5LiN54ix6K-06K-d6YOt5b6357qy_q75.webp