手写vue2响应式

    看过vue源码的都知道,vue中通过对data中的属性值进行监听实现了当数据变化时更新视图,其实实现的理论基础是比较简单的,只是结合到整个vue的组件化过程中后便变的贼秀。话不多说,直接撸
\bullet 理论基础

    Object.defineProperty,该api提供了对对象属性读写的更精确的控制,其对obj.a以及obj.a=newValue进行了操作前拦截。其参数三作为配置对象提供了对对象读写权限的修改控制方式,配置下的get和set方法则允许我们在操作前做一些额外的事情

(当obj.a时将触发get,obj.a=4时将触发set)

\bullet 实现

    \ast 像vue一样,我们也把data代理到实例上一份,可以直接在实例上访问


    \ast 对data进行遍历,这显然应当是一次递归过程,由于Object.defineProperty只支持对象形式,故对于基本数据类型,即是该递归的出口。同时由于代理到实例的_data和data指向同一引用,故通过实例对_data的操作能够触发data的响应式操作

        框红的地方主要是为了避免死循环,利用闭包修改外部变量,配合get达到肉眼修改的目的(其实只是获取的时候取得是外部缓存的值,实际上内部有没有修改?I don't know)

    \ast 既然已经对data中的每一层属性操作都架设了拦截,那么只需要在合适的时机收集依赖,在一定的条件下触发更新即可。那收集谁?收集到哪里?这里和vue一样,使用dep类收集watcher,至于watcher具体要干什么我不关心

        定义Watch类和Dep类,Watch类作为客户端,去执行具体的动作,Dep类则作为广播工具,适时通知到Watch。那么如何建立二者之间的关系呢?

(通过静态属性Target确保唯一性;发布订阅模式,get即订阅消息,set其发布者,dep相当于调度中心)

    \ast 最后,在get时调用depend,该方法传入dep并调用watch的addDep方法,即将dep保存到watcher实例又将watcher示例绑定到dep中,这样就完成了依赖收集(即:将watcher收集到dep中)。之后只需要在设置属性时调用notify通知watcher作更新即可

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容