Vue3 - Reactivity的核心流程

前言

这篇文章主要简述了vue框架在模块运行时如何做到的响应式的,我先阐述一下文章中会用到的相关概念

副作用函数(Effect)

是指那些会"依赖"响应式数据,并且当这些数据变化时需要重新执行的函数。 常见的有:模版渲染数据、计算属性、Watch、自定义 Effect

流程

创建一个响应式对象

js 复制代码
// 表面
const a = reactive({ num: 1 })

这里这时候reactive函数会将目标对象 { num: 1 } 转换 为Proxy代理对象,

这时候reactive函数到底干了什么?

看图可知,这时候 reactive 函数给 createReactiveObject 函数传了对象,以及用于普通对象的可变响应式代理的处理器 mutableHandlers,

而这整一个过程主要是对象和baseHandlers(处理器)传给Proxy类,创建了相应的Proxy代理对象

那么这个处理器给proxy带来了什么方法呢?

在baseHandlers中调用了createGetter和createSetter分别创建了代理对象的get和set函数,

get函数的作用是返回当前需要的值以及收集依赖,

set函数是用来设置并返回对象更新的值的,以及触发依赖

对象数据变动

dart 复制代码
let dummy // 用来创建副作用函数的相关变量

// 表面
const a = reactive({ num: 1 })

// 手动创建的副作用函数
effect(() => {
  console.log(`num 发生变化: ${a.num}`)
  dummy = a.num
})

// 会触发 Effect 执行
a.num++ 
响应式数据变更之前的准备操作

创建副作用函数(fn),它的内部需要访问num的,这时就会触发get中的依赖收集,

fn就会被传入给ReactiveEffect类创建出一个_effect实例【用来注册响应数据变化时需要执行的函数】,并用实例的方法run执行fn,

而run内部还会将这次创建的_effect实例赋值给全局的activeEffect,方便代理对象收集依赖 然后get操作会进行依赖收集,触发track操作 track操作用来找寻代理对象(a)的依赖合集,再通过代理对象的依赖合集找到对应的key(num)的依赖合集,并将当前的 activeEffect 添加到对应的对象的dep容器里去,完成依赖收集

响应式数据改变时

如果这时候对象的数据发生变更,那么会触发set操作,继而用trigger()触发依赖,即执行存在key的dep里的的依赖,即num的依赖

实践

第一次初始化的时候执行副作用函数,第二次trigger触发依赖执行副作用函数

相关推荐
wuhen_n30 分钟前
网络请求在Vite层的代理与Mock:告别跨域和后端依赖
前端·javascript·vue.js
小彭努力中30 分钟前
193.Vue3 + OpenLayers 实战:圆孔相机模型推算卫星拍摄区域
vue.js·数码相机·vue·openlayers·geojson
用户69371750013845 小时前
Google 正在“收紧侧加载”:陌生 APK 安装或需等待 24 小时
android·前端
蓝帆傲亦5 小时前
Web 前端搜索文字高亮实现方法汇总
前端
用户69371750013845 小时前
Room 3.0:这次不是升级,是重来
android·前端·google
漫随流水7 小时前
旅游推荐系统(view.py)
前端·数据库·python·旅游
踩着两条虫8 小时前
VTJ.PRO 核心架构全公开!从设计稿到代码,揭秘AI智能体如何“听懂人话”
前端·vue.js·ai编程
jzlhll1239 小时前
kotlin Flow first() last()总结
开发语言·前端·kotlin
蓝冰凌10 小时前
Vue 3 中 defineExpose 的行为【defineExpose暴露ref变量】详解:自动解包、响应性与实际使用
前端·javascript·vue.js
奔跑的呱呱牛10 小时前
generate-route-vue基于文件系统的 Vue Router 动态路由生成工具
前端·javascript·vue.js