简易响应式原理

1.收集依赖

收集依赖就是把需要把用到响应式的对象属性的函数存起来,只要你用到了我的属性,我就把你存起来.所以,需要创建一个类,管理依赖

 class Depend {
            constructor(){
                this.reactiveFn = new Set() //用set可以保证不会重复加入函数
            }

            addDepend(fn){
               this.reactiveFn.add(fn) //加入到对应属性依赖
            }

            notify(){
                this.reactiveFn.forEach(fn => {//属性改变时调用这些函数
                     fn()
                })
            }
         }
2.合理储存依赖

调用上面类方法可以创建一个属性依赖,但我们需要方便管理储存多个依赖,封装一个获取依赖的函数

   let weakMap = new WeakMap() //弱应用map
         function getDepend(obj,key){ //把对象和属性传进来
            let map = weakMap.get(obj) 
            if(!map){
                map = new Map()
                weakMap.set(obj,map)
            }
            
            let dePend = map.get(key)
            if(!dePend){
                map.set(key,new Depend())
                dePend = map.get(key)
            }
            return dePend
         }
3.创建依赖添加函数,响应式代理对象

依赖管理好后,创建响应式对象,添加依赖

  let activeFn = null
   function watchFn(fn){  //目前需手动把用到的函数添加进去       
            activeFn = fn
            fn()
            activeFn = null
   }
  function reactive(obj){
         return new Proxy(obj,{
            get:function(target,key,receiver){
                // console.log( getDepend(target,key),'sm')
                if(activeFn){
                    getDepend(target,key).addDepend(activeFn)
                }
                return Reflect.get(target,key,receiver) //Reflect对象方法避免直接调用原始对象
            },
            set:function(target,key,newVal,receiver){
                Reflect.set(target,key,newVal,receiver)
            //    dePend.notify()
              getDepend(target,key).notify()

            }
         })
    }
4.使用
   class Depend {
            constructor(){
                this.reactiveFn = new Set()
            }

            addDepend(fn){
               this.reactiveFn.add(fn)
            }

            notify(){
                this.reactiveFn.forEach(fn => {
                     fn()
                })
            }
         }
         
         let weakMap = new WeakMap()
         function getDepend(obj,key){
            let map = weakMap.get(obj)
            if(!map){
                map = new Map()
                weakMap.set(obj,map)
            }
            
            let dePend = map.get(key)
            if(!dePend){
                map.set(key,new Depend())
                dePend = map.get(key)
            }
            return dePend
         }
         
         let activeFn = null
         function watchFn(fn){        
            activeFn = fn
            fn()
            activeFn = null
         }
         
        function reactive(obj){
           return new Proxy(obj,{
            get:function(target,key,receiver){
                // console.log( getDepend(target,key),'sm')
                if(activeFn){
                    getDepend(target,key).addDepend(activeFn)
                }
                return Reflect.get(target,key,receiver)
            },
            set:function(target,key,newVal,receiver){
                Reflect.set(target,key,newVal,receiver)
            //    dePend.notify()
              getDepend(target,key).notify()

            }
         })
        }

         let obj = {
            name:'gw',
            age:18
          }

         let info = {
            address:'北京'
          }
        
       const objProxy = reactive(obj)
        setTimeout(() => {
            objProxy.name = '李白'
        }, 2000);
  
         watchFn(function(){
            console.log('name用', objProxy.name)
         })
         watchFn(function(){
            console.log('name用2',objProxy.name)
         })
         watchFn(function(){
            console.log('age用',objProxy.age)
         })
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值