Vue 3 的 reactive 对数组完全响应,但仅 push、pop、shift、unshift、splice、sort、reverse 等内置方法及 ref 重赋值能触发视图更新;直接索引赋值(arr[0] = val)或修改 length 不触发更新。

Vue 3 的 reactive 对数组本身是完全响应式的,但它的响应性有明确的触发边界——不是所有修改数组的方式都能被 Vue 自动侦测到。关键不在 reactive “不支持数组”,而在于你是否用了 Proxy 能拦截的操作。
哪些数组操作会自动更新视图?
Vue 3 基于 Proxy 对数组做了增强,以下内置方法调用后,视图会立即响应:
- push()、pop()、shift()、unshift():增删首尾元素
- splice():替换、删除、插入任意位置的元素(最常用也最推荐)
- sort()、reverse():原地排序或翻转
-
用 reactive 包裹后,配合 splice 替换某一项:例如
list.splice(2, 1, newItem) -
用 ref 包裹整个数组后重新赋值:例如
listRef.value = [1, 2, 3](此时响应性由 ref 保障)
哪些写法看似改了数组,但视图不会更新?
这些操作绕过了 Proxy 的 set 拦截器,Vue 无法追踪变化:
构建 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
-
直接通过索引赋值:如
arr[0] = 'new'❌ -
直接修改 length:如
arr.length = 0❌ -
用 Object.assign 或展开运算符“覆盖内部”却不重新赋值给响应式变量:如
Object.assign(arr, ['a', 'b'])❌(只改了内容,没通知 Proxy) -
把 reactive 数组整体替换为新数组:如
list = [1, 2, 3]❌(原 Proxy 引用丢失,响应链断裂)
想安全更新某一项,推荐这三种方式
假设 const list = reactive(['a', 'b', 'c']),要把第 1 项('b')换成 'x':
立即学习“前端免费学习笔记(深入)”;
-
用 splice:简洁、语义清晰、原生响应式 →
list.splice(1, 1, 'x')✅ -
把每一项都设为 reactive 对象:适合结构化数据 →
const list = reactive([{val: 'a'}, {val: 'b'}, {val: 'c'}]),然后list[1].val = 'x'✅(对象属性响应) -
改用 ref 包裹数组:尤其适合频繁整批替换 →
const list = ref(['a', 'b', 'c']),再list.value = ['a', 'x', 'c']✅(ref 保证整体赋值仍响应)
为什么 arr[index] = val 不行?原理上怎么理解?
因为 reactive 返回的是一个 Proxy 对象,它能拦截的是 set 操作(比如 obj.key = val),但 JavaScript 中对数组索引的赋值 arr[0] = val 实际触发的是数组原型上的 set 拦截 —— Vue 确实做了适配,但仅限于数组方法调用路径。直接索引赋值在 Proxy 层未被重写,等同于对原始数组操作,Proxy 无感知。本质不是 bug,而是设计取舍:保持数组行为接近原生,同时明确响应式契约。

















