el-table中toggleRowSelection选中方法不生效附解决方案

问题背景

最近在后台管理项目中,需求是需要在A弹窗中有个table表格和按钮,点击查询按钮B弹窗弹出,里面内容还是table表格,选择B弹窗中的table表格某些项,保存之后会把已选中的表格项带到A弹窗中。A弹窗中再次点击查询按钮,B弹窗此时table表格应该回显之前选中项。

遇到的问题,就是再次进入B弹窗的table表格未回显之前选中的某些表格项。通过排查原因是,打开B弹窗时候需要每次请求接口,获取表格数据,导致对象引用不同,所以使用el-table的toggleRowSelection() 选中方法无效。

失效原因

1. DOM渲染未完成

每次请求接口,数据更新后DOM会注销新建,导致我们勾选操作失效;可能是table表格相关的DOM渲染还未完成,无法调用toggleRowSelection() 方法,可以使用nextTick解决。

2. 数据源不符

数据源问题,我们每次请求回来的表格数据,即便数据一模一样,数据对象存储地址的指针不同也会导致失败。
toggleRowSelection 需要接收表格数据中的一项。如果传递的 row 对象与 el-table 的数据源不一致,方法将无法正确选中或取消选中行。

解决方法

1. 使用nextTick,目的是获取更新后的DOM元素

官方对其的定义:

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

2. 使用唯一标识符,确保数据对象一致性

可以维护一个 selectedRowIds 的集合来追踪选中的行,并在数据刷新后再重新选中这些行,主要看下B弹窗的代码:

<template>
    <el-dialog v-model="modelValue" title="选择数据" width="800" :before-close="onClose">
        <el-table ref="tableRef" :data="state.tableList" @selection-change="onSelectionChange">
            <el-table-column type="selection" width="50" />
            <el-table-column property="项目名称" label="projectName" width="150" />
            <el-table-column property="推荐分行" label="branchCode" width="100" />
        </el-table>
    </el-dialog>
</template
<script setup lang="ts">
import { ref, reactive, watch, nextTick } from 'vue'
import type { TableInstance }from 'element-plus'

const emit = defineEmits(['update:modelValue', 'select-rows'])
const onClose = () => {
    emit('update:modelValue', false)
}
// 从A弹窗传入的值
interface Props {
    modelValue: boolean
    branchCode: string
    year: number
    pushData: any
}

const state = reactive({
    tableList: [],
    selectionList: [] as any[], // 已选中的表格数据
    selectionedRowIds: new Set(), // 解决 toggleRowSelection() 无法选中行问题,因为每次重新请求接口,导致对象引用不同
})
watch(
    () => props.modelValue,
    (val) => {
        if (val) {
            handleData()
        }
    }
)
const tableRef = ref<TableInstance>()
const setDefaultCheckedKeys = (rows: TableRow[] | undefined) => {
    if (!rows) return
    // 遍历数组,更新选中之前选中的行
    rows.forEach((row: anyObj)) =>{
        if(state.selectionedRowIds.has(row.loanId)){
            nextTick(()=>{
                tableRef.value!.toggleRowSelection(row,true)
            })
        }
    }
}
async function handleData(){
    try {
       // await 等待请求接口获取表格数据, 否则后面setDefaultCheckedKeys方法未获取到表格数据,步骤省略。。。
       state.tableList = data?.data??[]

       // 更新 selectionedRowIds 集合
       state.selectionedRowIds.clear()
       props.pushData.forEach(item =>{
          state.selectionedRowIds.add(item.loanId)
       })
       setDefaultCheckedKeys(state.tableList)
    }catch(error){
        console.log(error)
    }
}
cosnt onSelectionChange = (selection:[]) =>{
    state.selectionList = selection
}
</script >

关键点

  • 使用 selectedRowIds:在数据刷新前后,使用唯一标识符来管理选中的行。
  • 表格数据刷新之后,遍历表格数组,和selectedRowIds存储的值作比较,如果存在说明是之前已选中的项;调用 tableRef.value!.toggleRowSelection(row, true) 设置选中项。
  • 确保 tableRef.value 的有效性:在进行选中操作前,确保 tableRef.value 是有效的;使用nextTick 确保Dom元素更新完毕。

通过这些方法,可以确保即使数据源更新,表格中的选中状态也能正确恢复。

参考:toggleRowSelection 失效原因及解决思路

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

铁锤妹妹@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值