ref包裹数组时,直接赋值(.value = newArray)完全响应式;调用push、splice等7个增强方法也有效,但必须作用于.value而非ref本身;索引赋值和length修改不触发更新,应改用splice或展开重赋。

ref 包裹数组时,直接赋值(.value = newArray)是完全响应式的,能立刻触发视图更新;而调用数组方法(如 push、splice 等)也有效,但前提是操作的是 .value 本身——不是对 ref 对象本身调用方法。
直接赋值:最稳妥、最推荐的方式
把新数组整体赋给 ref.value,Vue 能立即侦测到引用变化并刷新视图。这种方式逻辑清晰、兼容性强,且不受任何“非响应式操作”限制。
- ✅ 正确写法:
list.value = [1, 2, 3]、list.value = list.value.filter(x => x > 0)、list.value = [...list.value, newItem] - ⚠️ 注意:不能写成
list = ref([1, 2, 3])——这会丢失原有 ref 的响应式绑定,属于重新声明变量,旧模板不再追踪
使用数组方法:必须作用于 .value,且仅限 Vue 增强的变异方法
Vue 3 对 Array.prototype 上的 7 个方法做了响应式增强,但只对 ref.value 调用才生效。这些方法包括:push、pop、shift、unshift、splice、sort、reverse。
- ✅ 正确写法:
list.value.push(item)、list.value.splice(index, 1, newItem) - ❌ 错误写法:
list.push(item)(list是 ref 对象,不是数组)、list.value[0] = item(索引赋值不触发更新)、list.value.length = 0(修改 length 不触发)
按索引更新某一项:别硬改,用 splice 或重赋值
如果必须更新数组中特定位置的元素(比如编辑表格某行),不要直接写 list.value[i] = newValue,它不会刷新界面。
- ✅ 推荐方案一(splice):
list.value.splice(i, 1, newValue) - ✅ 推荐方案二(展开重赋):
list.value = [...list.value.slice(0, i), newValue, ...list.value.slice(i + 1)] - ? 小提示:Vue 3.2+ 开始,
reactive数组支持索引赋值,但ref数组仍不支持——所以 ref 场景下坚持用上面两种方式即可
避免常见陷阱:解包后存入数组会丢失响应性
如果你把 ref.value 的值取出来再塞进另一个数组(比如 const arr = [count.value]),这个新数组里的元素只是普通值,后续 count.value 变了,arr[0] 不会跟着变。
- ✅ 正确做法:若需动态响应,应存储 ref 本身(
[count, message]),模板中用item.value访问 - ❌ 错误做法:
const snapshot = [count.value]—— 这是一次性快照,不是响应式连接


















