当前位置: 首页> 财经> 创投人物 > 十大靠谱的咨询公司_江门网站优化方案_网络营销成功案例分析其成功原因_seo培训

十大靠谱的咨询公司_江门网站优化方案_网络营销成功案例分析其成功原因_seo培训

时间:2025/8/7 2:21:41来源:https://blog.csdn.net/ZhooooYuChEnG/article/details/145537809 浏览次数:1次
十大靠谱的咨询公司_江门网站优化方案_网络营销成功案例分析其成功原因_seo培训

响应式系统(Reactivity System)

1.1 基于 Proxy 的响应式代理

在 Vue 3 中,响应式系统的核心是使用 ES6 的 Proxy 来替代 Vue 2 里的 Object.defineProperty 方法,以此实现更加全面和强大的响应式追踪功能。下面我们来详细剖析这个过程。

响应式代理的实现代码
const reactive = (target) => {return new Proxy(target, {get(target, key, receiver) {track(target, key) // 依赖收集return Reflect.get(target, key, receiver)},set(target, key, value, receiver) {Reflect.set(target, key, value, receiver)trigger(target, key) // 触发更新return true}})
}
代码详细解释
  • reactive 函数:该函数接收一个目标对象 target 作为参数,返回一个使用 Proxy 代理后的新对象。Proxy 是 ES6 提供的一个强大特性,它可以拦截并重新定义对象的基本操作,比如属性的读取和设置。
  • get 拦截器:当访问代理对象的属性时,会触发 get 拦截器。
    • track(target, key):调用 track 函数进行依赖收集。依赖收集的目的是记录哪些副作用函数依赖于当前访问的属性,以便在属性值发生变化时能够通知这些副作用函数进行更新。
    • Reflect.get(target, key, receiver):使用 Reflect.get 方法获取目标对象的属性值。Reflect 是 ES6 新增的一个内置对象,它提供了一系列用于操作对象的方法,与 Proxy 配合使用可以更方便地实现对象的拦截操作。
  • set 拦截器:当设置代理对象的属性时,会触发 set 拦截器。
    • Reflect.set(target, key, value, receiver):使用 Reflect.set 方法设置目标对象的属性值。
    • trigger(target, key):调用 trigger 函数触发更新。当属性值发生变化时,需要通知所有依赖该属性的副作用函数重新执行。
相比 Object.defineProperty 的优势
  • 支持数组索引修改和 length 变化检测:在 Vue 2 中,使用 Object.defineProperty 来实现响应式时,对于数组的一些操作(如通过索引修改元素、修改 length 属性)无法直接检测到变化。而在 Vue 3 中,使用 Proxy 可以轻松地拦截这些操作,从而实现对数组的全面响应式追踪。
const arr = reactive([1, 2, 3]);
arr[0] = 10; // 可以正常触发更新
arr.length = 2; // 也可以正常触发更新
  • 自动追踪新增对象属性(无需 Vue.set:在 Vue 2 中,如果要给响应式对象新增一个属性,需要使用 Vue.set 方法才能让新增的属性也具有响应式特性。而在 Vue 3 中,由于使用了 Proxy,可以自动追踪对象新增的属性,无需额外的操作。
const obj = reactive({ a: 1 });
obj.b = 2; // 新增属性 b 会自动具有响应式特性
  • 深度监听嵌套对象(Lazy 模式,按需激活):Vue 3 的响应式系统会对嵌套对象进行深度监听,但采用的是 Lazy 模式,即只有在访问嵌套对象的属性时才会激活对该嵌套对象的响应式追踪,这样可以提高性能。
const nestedObj = reactive({inner: {c: 3}
});
// 当访问 nestedObj.inner.c 时,才会激活对 inner 对象的响应式追踪
1.2 依赖管理机制

Vue 3 的响应式系统采用了三层依赖管理体系,通过 WeakMapMapSet 来高效地管理依赖关系。

三层依赖管理体系的结构
  • TargetMap:是一个 WeakMap,用于存储目标对象到键的映射。WeakMap 的键必须是对象,并且这些对象是弱引用,即如果对象没有其他引用指向它,它可以被垃圾回收,这样可以避免内存泄漏。
  • DepsMap:是一个 Map,用于存储键到依赖集合的映射。每个键对应一个依赖集合,该集合存储了所有依赖于该键的副作用函数。
  • Dep:是一个 Set,用于存储具体的副作用函数。Set 是一种无序且唯一的数据结构,确保每个副作用函数只被存储一次。
依赖管理的代码实现
type Dep = Set<ReactiveEffect>;
type KeyToDepMap = Map<any, Dep>;
const targetMap = new WeakMap<any, KeyToDepMap>();function track(target: object, key: unknown) {if (!activeEffect) return;let depsMap = targetMap.get(target);if (!depsMap) {targetMap.set(target, (depsMap = new Map()));}let dep = depsMap.get(key);if (!dep) {depsMap.set(key, (dep = new Set()));}dep.add(activeEffect);
}
代码详细解释
  • 类型定义
    • Dep:定义为 Set<ReactiveEffect>,表示一个存储副作用函数的集合。
    • KeyToDepMap:定义为 Map<any, Dep>,表示一个存储键到依赖集合的映射。
  • targetMap:是一个全局的 WeakMap,用于存储所有目标对象的依赖信息。
  • track 函数:用于进行依赖收集。
    • if (!activeEffect) return;:如果当前没有活跃的副作用函数,则直接返回,不进行依赖收集。
    • let depsMap = targetMap.get(target);:从 targetMap 中获取目标对象对应的 DepsMap
    • if (!depsMap) { targetMap.set(target, (depsMap = new Map())); }:如果 DepsMap 不存在,则创建一个新的 Map 并存储到 targetMap 中。
    • let dep = depsMap.get(key);:从 DepsMap 中获取键对应的依赖集合。
    • if (!dep) { depsMap.set(key, (dep = new Set())); }:如果依赖集合不存在,则创建一个新的 Set 并存储到 DepsMap 中。
    • dep.add(activeEffect);:将当前活跃的副作用函数添加到依赖集合中。
1.3 副作用调度

Vue 3 的响应式系统基于调度器实现了异步更新队列,以提高性能和避免不必要的重复更新。

异步更新队列的实现代码
const queue = new Set();
let isFlushing = false;function queueJob(job) {queue.add(job);if (!isFlushing) {isFlushing = true;Promise.resolve().then(() => {try {queue.forEach(job => job());} finally {queue.clear();isFlushing = false;}});}
}
代码详细解释
  • queue:是一个 Set,用于存储需要执行的副作用函数。使用 Set 可以确保每个副作用函数只被存储一次,避免重复执行。
  • isFlushing:是一个布尔值,用于标记当前是否正在执行更新队列中的副作用函数。
  • queueJob 函数:用于将副作用函数添加到更新队列中。
    • queue.add(job):将副作用函数添加到 queue 中。
    • if (!isFlushing) { ... }:如果当前没有正在执行更新队列中的副作用函数,则启动异步更新。
      • isFlushing = true;:标记为正在执行更新。
      • Promise.resolve().then(() => { ... }):使用 Promise 实现异步执行。在微任务队列中执行更新队列中的副作用函数。
      • try { queue.forEach(job => job()); } finally { queue.clear(); isFlushing = false; }:遍历更新队列,执行每个副作用函数。执行完毕后,清空队列并将 isFlushing 标记为 false,表示更新完成。

通过这种异步更新队列的方式,Vue 3 可以将多次属性变化引起的副作用函数执行合并为一次,从而提高性能。例如,在短时间内多次修改响应式对象的属性,只会触发一次副作用函数的执行。

综上所述,Vue 3 的响应式系统通过基于 Proxy 的响应式代理、三层依赖管理机制和副作用调度,实现了高效、全面的响应式追踪和更新功能。

关键字:十大靠谱的咨询公司_江门网站优化方案_网络营销成功案例分析其成功原因_seo培训

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: