vue 3 中应使用 ref(set) 缓存选中 id 而非行对象,配合 computed 封装 isselected 函数、全选时直接赋值 set、仅在需要时通过 filter 映射 selectedrows,实现高效响应式选中管理。

在 Vue 3 中,用 ref 高效缓存表格选中行数据,关键不是“把整个行对象数组存进 ref”,而是**分离状态、按需同步、避免重复计算**。直接存 ref([]) 看似简单,但容易导致渲染卡顿、状态不同步或无法响应式更新。
用 Set + ref 缓存 ID,而非行对象
选中状态本质是“哪些 ID 被勾选”,不是“哪些完整对象被勾选”。用 Set 存 ID 比用数组更高效:
- 增删查都是 O(1),不随选中数量增长而变慢
- 天然去重,防止重复点击导致数据错乱
- 配合
ref使用时,selectedIds.value.has(id)是轻量判断,适合频繁调用
示例:
const selectedIds = ref(new Set())
搭配 computed 缓存 isSelected 函数,避免模板中反复 has
模板里写 :checked="selectedIds.value.has(item.id)" 会导致每次重渲染都执行 has,Vue 无法自动跳过。应封装为计算属性:
- 利用
computed的缓存机制,仅当selectedIds.value变化时才重新生成函数 - 函数本身无副作用,可安全用于
v-for内部
示例:
const isSelected = computed(() => (id) => selectedIds.value.has(id))
模板中使用::checked="isSelected(item.id)"
全选/取消全选时批量操作,不遍历原始数据
不要在全选回调里循环所有 tableData 并逐个 push 到数组——这既低效又破坏响应式一致性。正确做法是:
- 全选 → 直接赋值
selectedIds.value = new Set(totalIds) - 取消 → 直接赋值
selectedIds.value = new Set() - 不手动触发更新,
ref值变更会自动通知依赖
这样避免了对大数组的遍历和冗余对象创建,性能更可控。
需要行对象时再映射,不提前展开
业务中真正需要“选中的完整行数据”往往只在提交、导出等少数时刻。此时才从 tableData 中根据 selectedIds.value 提取:
- 定义一个
computed或方法:const selectedRows = computed(() => tableData.value.filter(row => selectedIds.value.has(row.id))) - 该计算属性只在依赖变化(ID Set 或 tableData)时执行,不会在每次渲染中运行
- 避免在
setup中用watch手动同步两个数组,增加维护成本
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










