vue响应式流程图

博客主要呈现了Vue响应式流程图,涉及Vue相关知识,与前端开发紧密相关。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

vue响应式流程图

在这里插入图片描述

### Vue 响应式原理详解 Vue响应式机制基于 JavaScript 中的 `Object.defineProperty` 方法来实现数据劫持,同时结合观察者模式和发布/订阅模式完成视图与模型之间的同步。以下是对其工作流程的具体分析: #### 1. **数据劫持** Vue 使用 `Object.defineProperty` 对象的属性进行拦截操作,将其转化为 getter 和 setter。每当访问或修改这些属性时,都会触发相应的逻辑。 ```javascript function defineReactive(obj, key, val) { const dep = new Dep(); // 创建依赖收集器 observe(val); // 递归观测嵌套对象 Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter() { if (Dep.target) { // 判断是否有 watcher 正在追踪此依赖 dep.depend(); } return val; }, set: function reactiveSetter(newVal) { if (newVal === val) return; val = newVal; // 更新值 observe(newVal); // 新值可能是对象,继续观测 dep.notify(); // 通知所有订阅者更新 } }); } ``` 这段代码展示了如何通过定义 getter 和 setter 来监控属性的变化[^3]。 --- #### 2. **依赖收集** 当组件初始化时,模板中的表达式会触发相应数据的 getter 函数,此时 Vue 将当前的 watcher 添加到对应的依赖列表中。这种行为被称为“依赖收集”。 ```javascript class Dep { constructor() { this.subs = []; // 订阅者列表 } depend() { if (Dep.target) { this.addSub(Dep.target); } } addSub(sub) { this.subs.push(sub); } notify() { this.subs.forEach(sub => sub.update()); } } // 当前正在运行的 watcher Dep.target = null; class Watcher { constructor(vm, exprOrFn, cb) { this.vm = vm; this.exprOrFn = exprOrFn; this.cb = cb; Dep.target = this; // 设置当前 watcher this.get(); // 初始化时触发 getter 收集依赖 Dep.target = null; // 清除 target } update() { this.run(); } run() { const newValue = this.getVmValue(this.vm, this.exprOrFn); if (newValue !== this.value) { this.value = newValue; this.cb.call(this.vm, newValue); } } getVmValue(vm, exprOrFn) { return typeof exprOrFn === 'function' ? exprOrFn.call(vm, vm) : vm[exprOrFn]; } } ``` 以上代码片段说明了依赖是如何被收集以及后续的通知过程[^4]。 --- #### 3. **数组的特殊处理** 由于原生数组方法不会触发 getter 或 setter,因此 Vue 需要对数组方法进行重写以支持响应式功能。具体来说,Vue 替换了部分数组原型上的方法(如 push、pop 等),使其能够重新触发依赖更新。 ```javascript const arrayProto = Array.prototype; export const arrayMethods = Object.create(arrayProto); [ 'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse' ].forEach(methodName => { const originalMethod = arrayProto[methodName]; def(arrayMethods, methodName, function mutator(...args) { const result = originalMethod.apply(this, args); const ob = this.__ob__; let inserted; switch (methodName) { case 'push': case 'unshift': inserted = args; break; case 'splice': inserted = args.slice(2); break; } if (inserted) ob.observeArray(inserted); ob.dep.notify(); return result; }); }); ``` 这部分代码实现了对数组变异方法的支持[^3]。 --- #### 4. **整体流程总结** ![Vue响应式原理](https://via.placeholder.com/800x400?text=Vue%E5%93%8D%E5%BA%94%E5%BC%8F%E5%8E%9F%E7%90%86) - **数据绑定阶段**:Vue 实例化过程中,将 data 转换为响应式对象。 - **模板编译阶段**:解析 DOM 结构并将其中的数据映射至响应式系统的 getter 上。 - **渲染阶段**:当用户交互引起数据变化时,setter 自动触发更新逻辑,最终反映到页面上。 --- ### 示例代码 以下是一个简单的 Vue 响应式模拟实现: ```javascript function observer(data) { if (!data || typeof data !== 'object') return; Object.keys(data).forEach(key => { defineReactive(data, key, data[key]); }); } observer({ msg: 'Hello World!', count: 0 }); function defineReactive(target, key, value) { const dep = new Set(); // 存储依赖关系 observer(value); // 深度遍历子属性 Object.defineProperty(target, key, { get() { if (Dep.target) { dep.add(Dep.target); } return value; }, set(newValue) { if (newValue === value) return; value = newValue; observer(newValue); // 如果新值是对象,则继续观测 dep.forEach(watcher => watcher.update()); // 通知所有依赖更新 } }); } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值