实现Vue3中的reactive

vue 3中实现响应式的主要是reactiveref 函数。那我们今天就来实现一个reactive

一、创建代理对象

vue3中的响应式的底层原理已经换成了proxy ,则reactive 函数返回的是一个proxy代理对象,我们先创建一个reactive.js文件

上面呢,我们简单实现了一个reactive函数,接受一个源对象,然后代理了源对象的get和set行为后返回一个代理对象。写个html,引入js测试一下

成功返回代理对象,并触发get和set行为

二、实现effect

第一步我们已经实现了代理对象,我们目前只能去监听代理对象的set和get操作,这样是远远不够的。如下

我们将age显示在页面上,两秒后去修改age属性,如何实现页面同步更新呢?

接下来引入一个新的函数 effect

effect 翻译过来就是作用的意思,那我们期望effect实现什么作用呢?当然是当代理对象更新属性触发set行为时,自动去执行某些操作。

好了,我们了一个目标,那就去实现它吧。新建一个effect.js文件,根据目标effect函数应该接受一个函数参数。

复制代码
此时的参数就是我们去修改dom节点的函数,并且这个函数要被执行。我们很容易就实现以下代码

此时,接收fn并执行,会触发函数中的代理对象的get行为。那我们如何将fn与代理对象的属性进行绑定呢?这就要引出另一个概念: 依赖收集

三、实现依赖收集

在哪一步进行依赖收集呢?从第二步就可以知道,我们在代理对象触发get行为的时候进行依赖收集。

首先,在触发get行为时,我们可以获取到源对象target,对象属性key。我们需要设计一下数据结构来存储对应的关系。

接下来就去实现依赖收集track函数

这里引入了一个activateEffect的变量,用于存储当前effect执行的函数

然后在代理对象的get行为触发的时候执行track就行了,如下

四、依赖触发

前面我们已经实习了依赖收集,下面到了依赖触发的阶段了。当代理对象触发set时,我们应该触发对应的函数。我们只需要根据原函数和字段来层层获取对应依赖就可以了,代码如下

在set函数触发的时候进行依赖触发

五、打包构建

之前都是直接在html中进行引入,这样不是很好,我们需引入一个专门打包js的工具,那就是rollup。我们只需要安装npm i rollup,然后在根目录创建rollup.config.js 文件,执行输入文件和输出文件即可。 配置文件内容如下:

其中format我们设置成iife,就是立即执行函数。然后我们指定一个打包文件入口index.js,然后在index.js中引入我们需要的函数。

然后在package.json 中配置打包脚本

然后只管build就行。再build生成的bundle文件引入html文件中。如下

然后使用插件live server打开html文件,发现两秒后网页上的内容发生了变化,则一个简单的reactive就实现了。

六、总结

为了实现reactive功能,我们引入了很多概念。首先就是返回Proxy对象,在返回代理的对象的过程中,我们监听了代理对象的get和set函数,在触发get时进行依赖收集,在触发set时进行依赖触发。同时,我们还引入了effect函数,自动执行传入函数,设计数据weakmap数据结构存储target、key、dep之间的关系。由于实现的比较简单,没有像Vue中的实现很多的类,如Dep,reactiveEffect类,大家如果感兴趣可以看一下我的GitHub,地址如下github.com/Wkb2317/my-... 也是跟着sunday老师的课程进行敲的代码,欢迎start,非常感谢。

相关推荐
Java陈序员1 天前
太香了!一款轻量级的 Elasticsearch 可视化管理工具!
vue.js·elasticsearch·vite
万物得其道者成1 天前
前端大整数精度丢失:一次踩坑后的实战解决方案(`json-bigint`)
前端·json
鹏北海1 天前
移动端 H5 响应式字体适配方案完全指南
前端
姜太公钓鲸2331 天前
ROM就是程序存储器,实际的存储介质是Flash闪存。上述描述中的程序存储器是什么意思?
开发语言·javascript·ecmascript
柳杉1 天前
使用AI从零打造炫酷医疗数据可视化大屏,源码免费拿!
前端·javascript·数据可视化
凌云拓界1 天前
前端开发的“平衡木”:在取舍之间找到最优解
前端·性能优化·架构·前端框架·代码规范·设计规范
zhengfei6111 天前
【XSS payload 】一个经典的XSS payload
前端·xss
简单Janeee1 天前
[Vue 3 从零到上线]-第四篇:组件化思维——把网页像积木一样拆解
javascript·vue.js·ecmascript
全栈老石1 天前
手写一个无限画布 #1:坐标系的谎言
前端·canvas
XW01059991 天前
4-11判断素数
前端·python·算法·素数