实现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,非常感谢。

相关推荐
军军君012 小时前
Three.js基础功能学习十三:太阳系实例上
前端·javascript·vue.js·学习·3d·前端框架·three
xiaoqi9223 小时前
React Native鸿蒙跨平台如何实现分类页面组件通过searchQuery状态变量管理搜索输入,实现了分类的实时过滤功能
javascript·react native·react.js·ecmascript·harmonyos
打小就很皮...3 小时前
Tesseract.js OCR 中文识别
前端·react.js·ocr
qq_177767374 小时前
React Native鸿蒙跨平台实现应用介绍页,实现了应用信息卡片展示、特色功能网格布局、权限/联系信息陈列、评分展示、模态框详情交互等通用场景
javascript·react native·react.js·ecmascript·交互·harmonyos
2603_949462104 小时前
Flutter for OpenHarmony社团管理App实战:预算管理实现
android·javascript·flutter
wuhen_n4 小时前
JavaScript内存管理与执行上下文
前端·javascript
Hi_kenyon4 小时前
理解vue中的ref
前端·javascript·vue.js
jin1233225 小时前
基于React Native鸿蒙跨平台地址管理是许多电商、外卖、物流等应用的重要功能模块,实现了地址的添加、编辑、删除和设置默认等功能
javascript·react native·react.js·ecmascript·harmonyos
2501_920931705 小时前
React Native鸿蒙跨平台医疗健康类的血压记录,包括收缩压、舒张压、心率、日期、时间、备注和状态
javascript·react native·react.js·ecmascript·harmonyos
落霞的思绪6 小时前
配置React和React-dom为CDN引入
前端·react.js·前端框架