Vue 3 中 reactive 管理选中项集合需保持引用不变,仅更新内部结构;必须用 reactive 包裹数组,通过 splice、push 等响应式方法操作,避免直接赋值新数组。

Vue 3 中用 reactive 管理批量操作的选中项集合,关键不是“替换整个对象”,而是保持响应式引用不变,只更新其内部结构。常见场景如表格多选、列表批量删除、勾选后统一提交等,选中项通常存为数组(selections: []),而这个数组本身必须是 reactive 创建的代理对象,才能被 Vue 正确追踪变化。
选中项集合必须用 reactive 包裹,不能直接赋值新数组
错误写法会丢失响应式:
-
data.selections = []—— 直接赋值新数组,破坏了原始代理引用,视图不更新 -
data.selections = [...oldItems]—— 同样是替换引用,Proxy 无法拦截
正确做法:复用原 reactive 数组,用响应式方法清空或填充:
- 清空:
data.selections.length = 0(⚠️注意:这在 Vue 3 中 不触发更新,慎用) - 推荐清空:
data.selections.splice(0)或data.selections.splice(0, data.selections.length) - 批量添加:
data.selections.push(...newItems)或data.selections.splice(0, 0, ...newItems) - 去重合并(如点击多行):
new Set([...data.selections, item])→ 转回数组后用splice替换
全选/反选逻辑要同步更新 selections 数组内容
全选时,不要新建数组,而是把目标数据源逐个推入或替换现有数组:
立即学习“前端免费学习笔记(深入)”;
构建 Shopify 嵌入式应用(Embedded App)的开发技能:基于 @shopify/shopify-app-react-router + React Router v7 + Admin API 2026-04。覆盖 shopifyApp 配置、authenticate.admin 的 GraphQL/REST 调用、Webhook 校验、Session 存储、订阅计费、App Bridge 导航、部署,并新增:适用场景判断、安全最佳实践、错误处理与容错、最佳实践、常见问题 FAQ、高级场景。G
- 全选:
data.selections.splice(0, data.selections.length, ...data.dataList) - 反选:先生成差集数组,再整体替换:
const unselected = data.dataList.filter(x => !data.selections.some(y => y.id === x.id)); data.selections.splice(0, data.selections.length, ...unselected)
这样既保持 data.selections 是同一个 reactive 引用,又确保每次变更都走响应式路径(splice 是 Vue 3 原生支持的响应式数组方法)。
配合 computed 和 watch 实现联动反馈
选中项集合常需驱动其他状态,比如“已选数量”“批量操作按钮是否禁用”。建议用 computed 派生,而非手动维护:
const selectedCount = computed(() => data.selections.length)const isAnySelected = computed(() => data.selections.length > 0)- 需要深度监听(如选中项内部字段变化影响按钮)时,加
{ deep: true }选项
避免在 watch 里对 selections 做赋值操作,应专注副作用(如请求接口、更新 UI 状态)。
嵌套结构或带 ID 的选中项,注意去重与引用一致性
如果 dataList 是对象数组,且每项有唯一 id,选中项应保存对象引用(非深拷贝),否则修改原数据时选中项不会同步更新:
- ✅ 正确:点击某行时
selections.push(item)——item是dataList中的原引用 - ❌ 错误:
selections.push({ ...item })—— 新对象,脱离响应式链路 - 去重可基于 id:
if (!selections.some(s => s.id === item.id)) selections.push(item)

















