返回

Vue3 Reactivity 源码学习笔记

前端







## 引言

Vue3 是一个渐进式的 JavaScript 框架,它允许您以一种声明式的方式构建用户界面。Vue3 的核心是它的响应式系统,它允许您跟踪数据的变化并自动更新用户界面。

## 基本构建

在 package 文件夹下创建 reactivity 文件夹,并在其中创建 index.js 文件。在 index.js 文件中,首先需要导入必要的模块,包括 Vue、vue-demi 和 mini-create-vue-context。

```javascript
import { Vue, vueDemi, miniCreateVueContext } from "vue-demi";
import { createReactivityHandler, createGetter, createSetter } from "./reactivityHandler";

接下来,需要定义一个 Reactivity 类,这个类将负责管理响应式数据的创建和销毁。

export class Reactivity {
  constructor() {
    this._data = {};
    this._activeEffects = [];
  }

  // 创建响应式数据
  createReactive(target) {
    return new Proxy(target, createReactivityHandler(this));
  }

  // 添加依赖
  addEffect(effect) {
    this._activeEffects.push(effect);
  }

  // 运行依赖
  runEffects() {
    this._activeEffects.forEach((effect) => effect());
  }
}

响应式系统

Vue3 的响应式系统是基于 Proxy API 实现的。Proxy API 允许您创建一个代理对象,它可以拦截对目标对象的访问和修改。当您对代理对象进行访问或修改时,代理对象会触发相应的拦截器函数,您可以在拦截器函数中执行一些自定义操作。

在 Vue3 中,响应式数据就是使用 Proxy API 创建的代理对象。当您访问或修改响应式数据时,代理对象会触发相应的拦截器函数,拦截器函数会通知 Vue3 的依赖收集系统,依赖收集系统会将当前正在执行的函数添加到响应式数据的依赖列表中。

当响应式数据发生变化时,Vue3 的依赖收集系统会遍历响应式数据的依赖列表,并执行这些依赖函数。这样,您就可以在响应式数据发生变化时自动更新用户界面。

依赖收集

Vue3 的依赖收集系统是基于栈的。当您访问或修改响应式数据时,Vue3 会将当前正在执行的函数添加到栈中。当响应式数据发生变化时,Vue3 会从栈中弹出当前正在执行的函数,并执行这些函数。

Vue3 的依赖收集系统非常高效,它只需要遍历一次栈,就可以收集到所有需要执行的依赖函数。

视图更新

当响应式数据发生变化时,Vue3 会执行依赖收集系统收集到的依赖函数。这些依赖函数通常是组件的更新函数。当依赖函数执行时,它会重新渲染组件的模板,并更新用户界面。

Vue3 的视图更新系统非常高效,它只