vue 3 的 reactive 对数组本身响应,但不能用等号整体替换,否则丢失响应性;应使用 push、splice 等内置方法,或封装为 reactive({ list: [] }) 后赋值 state.list = newdata,或改用 ref([]) 后赋值 value。

Vue 3 的 reactive 对数组本身是响应式的,但**不能直接用等号(=)整体替换数组**,否则会丢失响应性——因为新数组不是 Proxy 代理对象,Vue 无法追踪变化。
✅ 响应式更新数组的正确方式
只要操作的是同一个 reactive 数组实例,以下写法都能触发视图更新:
-
使用内置方法:如
push()、pop()、shift()、unshift()、splice()、sort()、reverse() -
用
splice()替换某一项:例如list.splice(0, 1, newItem),语义清晰且稳定 -
逐项赋值(前提是数组元素本身是响应式对象):如
list[0].name = 'new'—— 因为对象属性可被 Proxy 拦截
❌ 导致响应失效的常见错误
这些写法看似改变了数据,但 Vue 无法侦测,界面不会刷新:
- 直接索引赋值:
arr[0] = newValue - 修改 length:
arr.length = 0 - 整体重新赋值:
arr = newArray(覆盖了原 Proxy 实例) - 用
Object.assign(arr, [...])或展开运算符“就地覆盖”但未触发 setter
? 三种安全的重新赋值策略
当必须用后端返回的新数组完全替换旧数据时,推荐以下方案:
-
封装一层对象(最常用):定义
const state = reactive({ list: [] }),再赋值state.list = newData—— 因为修改的是响应式对象的属性,不是替换整个 reactive 变量 -
改用
ref:声明const list = ref([]),后续用list.value = newData,天然支持整体替换 -
用
splice清空并插入:如list.splice(0, list.length, ...newData),复用原数组引用,零额外开销
? 小贴士:怎么选 reactive 还是 ref?
简单记:ref 适合基本类型和需要整体替换的数组;reactive 更适合结构固定、频繁局部更新的对象或嵌套数组。若数组元素是对象,建议用 reactive([{...}, {...}]),这样既能响应 arr[i].prop = xxx,又便于组织逻辑。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










