vue响应式本质是通过数据劫持建立数据变化与视图更新的自动联动:vue2用object.defineproperty,vue3用proxy拦截读写;依赖收集在首次渲染时完成,派发更新通过dep通知watcher异步批量执行。

Vue 响应式数据追踪,本质是建立「数据变化」与「视图更新」之间的自动联动。它不靠轮询,也不依赖手动刷新,而是通过底层拦截机制,在数据被读取和修改的瞬间完成依赖记录与通知分发。
数据劫持:让读写操作可感知
Vue 在初始化 data 时,会对每个属性进行“包装”,使其具备可观测性:
- Vue 2 使用 Object.defineProperty 为对象属性添加 getter 和 setter —— 读属性触发 getter,改属性触发 setter
- Vue 3 使用 Proxy 代理整个对象,能拦截属性访问、新增、删除、数组索引赋值等所有操作,能力更完整
- 原始值(如字符串、数字)无法直接劫持,所以 Vue 要求响应式数据必须是对象或数组,且需在实例创建前定义好结构
依赖收集:谁用了这个数据,就记下来
当组件首次渲染时,模板中访问 {{ name }} 会触发 name 的 getter,此时系统就知道:“当前正在执行的渲染逻辑”依赖这个字段:
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- 每个响应式属性内部关联一个 Dep(依赖管理器),类似一个订阅者列表
- 每个组件对应一个 Watcher(观察者),它在渲染过程中主动“登记”自己用到的响应式字段
- 这个过程只在首次渲染或计算属性求值时发生,不是每次访问都重复收集
派发更新:数据一变,立刻通知相关方
当你执行 this.count++,setter 被触发,流程立即启动:
- setter 内部调用 Dep 的 notify() 方法
- Dep 遍历所有已登记的 Watcher,调用它们的 update() 方法
- Watcher 不直接操作 DOM,而是把更新任务推入异步队列,等下一个 tick 批量执行,避免重复渲染
常见盲区:哪些变动 Vue 看不见?
不是所有赋值都会触发更新,关键看是否经过响应式通道:
-
对象新增属性:如
this.obj.newKey = 'val'—— Vue 2/3 默认不响应,需用Vue.set或reactive({ ...obj, newKey: val }) -
数组索引直接赋值:如
this.list[0] = 'a'—— 不触发更新,应改用splice或Vue.set -
直接替换数组/对象引用:如
this.list = [...this.list]是响应的,但this.list = null后再赋新数组,旧依赖已断开
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









