elementui el-table表格实现翻页和搜索均保持勾选状态(后端分页)
·
需求:不管是页面切换还是通过搜索获取数据,都要保持已选中的行保持勾选状态,同时将选中行的内容以标签的形式显示出来,当点击关闭标签时可以对应取消选中状态,点击行中的任意位置也可以切换选中状态,单独勾选复选框一样可以达到要求。
由于需求相对还是蛮复杂的,直接使用row-key和reserve-selection,难以实现。所以直接通过书写代码来控制表格的勾选状态。
注意:我使用的是vue3 + ts!!!!
1. 第一步:书写html代码
给el-table添加对应勾选的监听事件,row-click用于监听鼠标选中某行时的勾选事件(不需要可去掉,我的需求是鼠标选中某行也要勾选);selection-change用于监听鼠标点击某行前面的勾选框、选中某行实现的勾选、表格左上角的全选,三种状态的事件;select用于监听框勾选数据行的 Checkbox 时触发的事件;select-all用于监听鼠标点击表格左上角的全选框。
<!-- 已选择点检项 --> <el-row align="middle" class="selected" justify="space-between" type="flex" > <el-col :span="24"> <span>已选择:</span> <template v-if="selectedCheckOptions"> <el-tag v-for="(item, i) in selectedCheckOptions" :key="i" closable :disable-transitions="false" @close="handleCloseTag(item, i)" > {{ item }} </el-tag> </template> </el-col> </el-row> <!-- 表格部分 --> <el-table ref="multipleTableRef" :data="gridData" :header-cell-style="{ 'background-color': '#fafafa', color: '#000', }" size="small" style="width: 100%" @row-click="handleClickTableRow" @select="onTableSelect" @select-all="selectSingleTableAll" @selection-change="handleChange" > <el-table-column type="selection" width="50" /> <el-table-column fixed label="序号" type="index" width="60" /> <el-table-column label="点检项" prop="itemName" /> <el-table-column label="分类" prop="itemTypeName" /> </el-table> <!-- 分页 --> <div class="page"> <el-pagination v-model:currentPage="currentPage" layout="total, prev, pager, next" small :total="total" @current-change="handleCurrentChange" /> </div>
2. 所需数据
// 只将表格中设计到需求的重要数据进行展示 const modelInfo = reactive({ // 当前所在页面的表格数据 gridData: [], // 添加点检项表格全部数据 tableData: [], tableAllSelectedId: [] as any, // 保存表格勾选的全部id tableAllSelectedRow: [] as any, // 保存表格勾选的行数据 selectedCheckOptions: [] as any, // 已选择的点检项 }) // 获取已选择的点检项 modelInfo.selectedCheckOptions = computed(() => { return modelInfo.tableAllSelectedRow.map((r: any) => r.itemName) })
3.所需方法
(1)从后台获取表格的分页数据的方法
// 获取表格数据的方法 (这里根据后端给的接口进行获取即可) const getCheckItemData = () => { checkItemList({ itemName: formInline.checkOption, itemTypeId: formInline.itemTypeId[formInline.itemTypeId.length - 1], filter: [], paging: { dir: 'DESC', limit: modelInfo.pageSize, page: modelInfo.currentPage, sort: 'createTime', start: 0, }, }).then((res: any) => { modelInfo.gridData = res.data.records // 条数必须是数字才可以显示在分页控件中 modelInfo.total = parseInt(res.data.total) // 关键代码(实现已勾选行数据保持选中状态) nextTick(() => { modelInfo.gridData.forEach((item: any) => { if (modelInfo.tableAllSelectedId.indexOf(item.itemId) > -1) { multipleTableRef.value?.toggleRowSelection(item, true) } else { multipleTableRef.value?.toggleRowSelection(item, false) } }) }) }) }
(2)当选择项发生变化时触发的方法
// 当选择项发生变化时会触发该事件 const handleChange = (val: any) => { // 将获取到的id存入tableAllSelectedId数组中 val.forEach((item: any) => { if (modelInfo.tableAllSelectedId.indexOf(item.itemId) === -1) { modelInfo.tableAllSelectedId.push(item.itemId) modelInfo.tableAllSelectedRow.push(item) } }) }
(3)点击表格某一行的方法
// 点击表格某一行的方法 const handleClickTableRow = (row: any) => { // 判断当前行是否已选中 if ( findIndexInObejctArr( JSON.parse(JSON.stringify(modelInfo.tableAllSelectedRow)), row, 'itemId' ) > -1 ) { const index = modelInfo.tableAllSelectedId.indexOf(row.itemId) modelInfo.tableAllSelectedId.splice(index, 1) modelInfo.tableAllSelectedRow.splice(index, 1) nextTick(() => { modelInfo.gridData.forEach((item: any) => { if (modelInfo.tableAllSelectedId.indexOf(item.itemId) > -1) { multipleTableRef.value?.toggleRowSelection(item, true) } else { multipleTableRef.value?.toggleRowSelection(item, false) } }) }) } else { multipleTableRef.value?.setCurrentRow(row) multipleTableRef.value!.toggleRowSelection(row, true) } }
(4)勾选数据行的 Checkbox 时触发的方法
// 勾选数据行的 Checkbox 时触发的方法 const onTableSelect = (rows: any, row: any) => { // 判断是点击了表格勾选还是取消勾选,true为选中,0或false是取消选中 const selected = rows.length && rows.indexOf(row) !== -1 if (!selected) { // 如果点击取消勾选 const index = modelInfo.tableAllSelectedId.indexOf(row.itemId) modelInfo.tableAllSelectedId.splice(index, 1) // 取消勾选,则删除id modelInfo.tableAllSelectedRow.splice(index, 1) // 取消勾选,则删除数据 } }
(5)表格全选触发的方法
// 表格全选触发的方法 const selectSingleTableAll = (selection: any) => { // 获取当前页码所显示的数据 const a: any = modelInfo.gridData // 获取当前页勾选的数据 const b = selection let flag_inCurrentPage selection.forEach((item: any) => { if (item.itemId === a[0].itemId) { flag_inCurrentPage = true return } }) const flag = a.length === b.length && flag_inCurrentPage if (flag) { // 切换成了全选状态 modelInfo.gridData.forEach((r: any) => { if (modelInfo.tableAllSelectedId.indexOf(r.itemId) === -1) { modelInfo.tableAllSelectedId.push(r.itemId) // 如果点击全选就保存全部id modelInfo.tableAllSelectedRow.push(r) //如果点击全选就保存全部数据 } }) } else { // 切换成了非全选状态 modelInfo.tableAllSelectedId = [] modelInfo.tableAllSelectedRow = [] } }
(6)查找对象在对象数组中位置的方法
// 查找对象在对象数组中的位置 findIndexInObejctArr: function(arr, obj) { for (let i = 0, iLen = arr.length; i < iLen; i++) { if (arr[i].deliverId === obj.deliverId) { return i } } return -1 }
(7)删除标签的方法
// 删除标签的方法 const handleCloseTag = (tag: string, index: number) => { // 先删除保存表格勾选的全部行数据中对应的数据,以及保存表格勾选的全部行id中对应的数据 modelInfo.tableAllSelectedId.splice(index, 1) modelInfo.tableAllSelectedRow.splice(index, 1) // 再根据已勾选的全部id来将对应行选中 nextTick(() => { modelInfo.gridData.forEach((item: any) => { if (modelInfo.tableAllSelectedId.indexOf(item.itemId) > -1) { multipleTableRef.value?.toggleRowSelection(item, true) } else { multipleTableRef.value?.toggleRowSelection(item, false) } }) }) }
(8)切换页码的方法
const handleCurrentChange = (val: number) => { modelInfo.currentPage = val getCheckItemData() }
(9)查询方法
// 搜索方法 const onSearch = () => { modelInfo.currentPage = 1 getCheckItemData() }
(10)确认添加的方法(由于我的表格是出现在弹出层中的,故增加了此方法,该方法和本文章的需求无关,可以直接忽视)
// 确认添加点检项的方法 const confirmAdd = () => { modelInfo.checkOptions = modelInfo.tableAllSelectedRow dialogAddVisible.value = false // 清除搜索内容 formInline.checkOption = '' formInline.itemTypeId = [] modelInfo.currentPage = 1 getCheckItemData() }
4.效果图
(1)选中的会在上面同步显示
(2)跨行也能保留选中状态和标签
(3)搜索也一样能保留选中状态
借鉴:elementui el-table表格实现跨页(翻页)保存勾选状态(后端分页)_公孙元二的博客-CSDN博客_el-table跨页勾选
更多推荐
已为社区贡献4条内容
所有评论(0)