手写 Vue 源码 === reactive 方法
目录
1. 响应式系统概述
2. Proxy与Reflect的应用
3. 响应式对象的创建
4. WeakMap的使用
主要特点
WeakMap 与 Map 的区别
应用场景
5. 依赖收集与触发更新
6. 响应式标记
7. 性能优化
8. 与Vue2的对比
9. 实际应用示例
10. 总结
Vue3的响应式系统是其核心特性之一,它允许我们以声明式的方式构建交互式用户界面。本文将深入探讨Vue3响应式系统的实现原理,特别是@vue/reactivity
包的内部工作机制。
1. 响应式系统概述
Vue3的响应式系统主要由以下几个部分组成:
- reactive: 创建响应式对象
- effect: 副作用函数,当依赖的响应式数据变化时自动执行
- baseHandler: 定义Proxy的处理器
这些组件协同工作,构成了一个高效的响应式系统。
2. Proxy与Reflect的应用
Vue3的响应式系统使用ES6的Proxy API来拦截对象的操作,结合Reflect API来执行默认行为。
baseHandler.ts
export enum ReactiveFlags {IS_REACTIVE = "__v_isReactive",
}
// 「Proxy 需要搭配 Reflect 使用 处理get set」
export const mutableHandlers: ProxyHandler<any> = {get(target: any, key: any, receiver: any) {// 如果访问的是代理对象的属性,直接返回if (key === ReactiveFlags.IS_REACTIVE) {return true;}// 依赖收集 todo...return Reflect.get(target, key, receiver); // 等价于receiver[key]},set(target: any, key: any, value: any, receiver: any) {// 找到属性 让对应的 effect 执行// 「触发更新 todo...」return Reflect.set(target, key, value, receiver);},
};
这里的mutableHandlers
定义了如何拦截对象的属性访问和修改操作:
- get: 当访问响应式对象的属性时,除了返回属性值,还会进行依赖收集
- set: 当修改响应式对象的属性时,除了设置新值,还会触发更新
使用Reflect
而不是直接操作对象的原因是为了保持正确的this
上下文,特别是在处理getter和setter时。
3. 响应式对象的创建
reactive.ts
import { isObject } from "@vue/shared";
import { mutableHandlers, ReactiveFlags } from "./baseHandler"