手写Vue2响应式原理,definePorperty,依赖收集

都知道Vue2响应式原理用的是definePorperty,那到底是怎么实现的,下面就来逐步分析去实现响应式的页面更新。

首先,在创建Vue实例的时候,会用Observer将data中的对象通过definePorperty重新定义一遍。

如:

//data

data:{
    msg:'hello',
    num:0
}

//change
change(){
    document.innerHtml=msg  
}
change()//页面展示hello
msg='hello world'  //数据更新页面不发生变化

//Observer
    function observer(data){
    for(let key in data){
        let temp=data[key]  //定义一个暂时变量,
        Object.defineProperty(data,key,{
            get:function(){
                return temp    
            },
            set:function(val){
                temp=val    //为什么要这样做,如果在set,get里直接设置date[key] ,就成了无限递归卡死
            },
        })
    }
}

到这里仅仅只是对每个变量进行了重写,但是如果更新了数据,页面并不会发生改变,因为并没有重新调用change方法,所以页面的内容没有重新赋值仍是hello。如果能在每次set完之后,就去执行change函数,那就能做到页面更新,但如果多个函数依赖到此数据就麻烦了。

所以接下来,我们要收集依赖此数据的函数或变量(收集依赖),然后实现页面更新(派发更新)

如:

//data

data:{
    msg:'hello',
    num:0
}

//change

change(){
    document.innerHtml=msg  
}
window.__func=change  //因为会可能有很多个页面要依赖到此数据,所以定义一个全局变量来暂时保存这个函数。
change()  //change函数里先获取msg进入get函数,再设置msg进入set函数
window.__func=null  //当依赖收集完后清空,以便于收集下一个函数
msg='hello world'  

//Observer
    function observer(data){
    for(let key in data){
        let temp=data[key]  
        let funcs=[]  //这里定义一个数组来存要依赖到的函数们
        Object.defineProperty(data,key,{
            get:function(){
                funcs.push(window.func)  //每次调用这个数据,就会执行get函数,然后在这里把依赖存起来,当改变这个数据时,再去set函数里去执行所有的依赖
                return temp    
            },
            set:function(val){
                temp=val   
                for(var i=0 ; i<funcs.length ; i++){
                    funcs[i]()   //调用所以的依赖,页面去重新渲染
                }
            },
        })
    }
}

还应该在收集依赖时,判断是否为空,更加严谨,这里就不再写了。

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值