VUE3 EL-TABLE切换单选多选时scope的插槽等会出现渲染错误

<template>
<el-table
:data="tableData"
row-key="id"
@selection-change="handleSelectionChange"
@current-change="tableCurrentChange"
ref="multipleTable"
highlight-current-row>
<!-- 多选框 -->
<el-table-column type="selection" width="55" align="center" fixed="" v-if="checked"></el-table-column>
<!-- 自定义加载表格列 -->
<el-table-column type="index" label="序号" width="50" align="center" fixed="left"/>
<el-table-column prop="id" label="主键" width="110" show-overflow-tooltip sortable v-if="false"/>
<el-table-column prop="bookingState" label="订舱" width="70" show-overflow-tooltip sortable align="center" fixed="left">
<template #default="scope">
<el-tag type="info" effect="dark" v-if="scope.row.bookingState=='无'"> 无 </el-tag>
<el-tag type="warning" effect="dark" v-else-if="scope.row.bookingState=='正操作'"> 正操作 </el-tag>
<el-tag type="success" effect="dark" v-else-if="scope.row.bookingState=='已完成'"> 已完成 </el-tag>
</template>
</el-table-column>
</el-table>
</template>
<script lang="ts" setup name="airOut">
//引用省略...
const loading = ref(false);
const tableData = ref<any>([]);
const checked = ref(false);
//切换单选多选
const changeChecked=()=>{
//清空单选选中框
multipleSelection.value = undefined;
//清空单选选中的数据(单选数据在多选数据数组中)
//cargoCurrent.value = null;
//清空多选选中的数据
multipleSelection.value = [];
//清空单选(清空单选选项及其单选样式)
multipleTable.value.setCurrentRow();
//清空多选(//清空多选选项及其多选框选择项)
multipleTable.value.clearSelection();
}
</script>
我是用v-if来控制切换单选与多选状态,而在此之前,如是否订舱字段,使用了scope插槽对数据再次进行处理,若我切换单选多选状态,会出现表格数据渲染错位/缺失等异常情况。
最终解决方案:
在切换单选多选时,改变表格绑定的KEY并强制改变值实现重新渲染。
//切换单选多选
const changeChecked=()=>{
//清空单选选中框
multipleSelection.value = undefined;
//清空单选选中的数据(单选数据在多选数据数组中)
//cargoCurrent.value = null;
//清空多选选中的数据
multipleSelection.value = [];
//清空单选(清空单选选项及其单选样式)
multipleTable.value.setCurrentRow();
//清空多选(//清空多选选项及其多选框选择项)
multipleTable.value.clearSelection();
//强制刷新el-table表格
tableKey.value++;
}
deepseek解题思路:
一、问题核心原因
1. 组件复用导致的渲染错乱
当使用 v-if
控制表格列的显隐时,Vue 会触发 el-table
的完整重渲染。由于 el-table
内部的行数据索引(scope.index
)或虚拟 DOM 复用机制未及时更新,导致插槽内容与行数据错位关联。
2. 响应式依赖断裂scope.row
的响应式依赖链可能在列切换时被破坏(如 bookingState
属性未被深度监听),导致插槽模板无法正确追踪数据变化。
二、解决方案(任选其一)
方案1:强制刷新表格Key
为 el-table
添加唯一标识 key
,在切换多选框时强制刷新表格实例,避免复用旧渲染树。
<el-table
:data="tableData"
:key="tableKey" <!-- 关键点 -->
>
<el-table-column
v-if="checked"
type="selection"
width="55"
></el-table-column>
<el-table-column prop="bookingState" label="订舱">
<template #default="scope">
<!-- 标签渲染逻辑 -->
</template>
</el-table-column>
</el-table>
<script setup>
const checked = ref(true);
const tableKey = ref(1);
// 切换多选框时触发
const toggleCheck = () => {
checked.value = !checked.value;
tableKey.value++; <!-- 强制刷新 -->
};
</script>
优势:彻底解决 DOM 复用导致的错位问题12。
方案2:用v-show替代v-if
通过 CSS 隐藏列而非销毁组件,保留表格内部状态一致性。
<el-table-column
type="selection"
width="55"
v-show="checked" <!-- 替换v-if -->
></el-table-column>
注意:需配合 <style>
覆盖 ElementUI 默认样式(部分版本隐藏列仍占用布局空间):
.el-table .hidden-column {
display: none !important;
}
适用场景:需要保留勾选状态的场景23。
方案3:插槽内容动态Key绑定
为插槽内的 el-tag
添加与行数据关联的 key
,确保内容更新触发重新渲染。
<template #default="scope">
<el-tag
:key="scope.row.id + '_tag'" <!-- 动态唯一Key -->
:type="getTagType(scope.row.bookingState)"
>
{{ scope.row.bookingState }}
</el-tag>
</template>
优势:精准控制插槽内容更新,避免局部渲染错位14。
操作验证流程
- 在 Vue Devtools 中检查
scope.row
数据是否与当前行匹配 - 监听
el-table
的@selection-change
事件,确认勾选状态与数据关联性 - 使用
console.log(scope.$index)
输出行索引,观察切换列时的索引变化1
方案选择建议
强制Key刷新 | 频繁切换且数据量大的场景 | 可能引发短暂性能损耗 |
v-show替代 | 需保留勾选/滚动条位置的场景 | 需处理隐藏列布局问题 |
插槽Key绑定 | 局部渲染异常的补充方案 | 需确保行数据有唯一标识字段 |