Vue响应式系统之收集依赖原理。

为什么要收集依赖?

举个例子:

// 假设我们有多个Vue对象
// 这个全局变量需要在所有Vue对象都能进行展示
let obj = {
  count:0
}
let vm1 = new Vue({
  template:`<div>{{count}}</div>`,
  data:obj
})
let vm2 = new Vue({
  template:`<div>{{count}}</div>`,
  data:obj
})
//这时候我们要对象全局变量进行修改
//修改后还需要让count知道是谁依赖了自己,然后count变更的时候通知依赖自己的对象(vm1、vm2)
//最后vm1、vm2进行视图更新
obj.count = 1;

下面来实现依赖收集:

// Dep订阅者
class Dep{  
  constructor(){
    this.watcherArr = []; // 存放依赖
  }
  addWatcherArr(watcherArr){  // 添加依赖
   if(watcherArr){
       this.watcherArr.push(watcherArr)
   }
  }
  notify(){   // 更新视图
    this.watcherArr.forEach(obj=>{
      obj.update();
   })
  }
}

// 观察者
class Watcher{
  constructor(){
  // 该对象被创建时赋值到Dep._this,获取属性时会用到
   Dep._this = this;
  }
  update(){
    console.log('视图更新了!')
  }
}

function defineReactive(obj,key,val){
  const dep = new Dep(); // 创建订阅者,好进行收集依赖、更新视图
  Object.defineProperty(obj,key,{
      enumerable: true,
      configurable: true,
      get:()=>{
        dep.addWatcherArr(Dep._this); // 收集依赖
        return val;
     },
     set:(newVal)=>{
         if(newVal===val) return;
         val = newVal;
         dep.notify(); // 数据变更后通知更新视图
     }
  })
}

function observers(value){
  if(!value || (typeof value !=="object")){return}
  Object.keys(value).forEach(key=>{
      return defineReactive(value,key,value[key]);
  })
}

class Vue {
  constructor(options){
    this.data = options.data;
    observers(this.data);
   // 依赖收集的前提条件有两个:触发get方法、创建一个Watcher对象
   // 以上两个条件已满足,这时候update方法更新了
    new Watcher();
    this.data.age  = 18; // 触发set
    // 这里只是通过打印的方式触发get方法读取、实际的话只要通过render()进行渲染,所有的依赖都会被读取
    this.data.age; // 触发get方法
    console.log(this.data.age); 
  }
}
const app = new Vue({
  data:{
    name:'张三',
    age:25
  }
})
Dep._this = null; // 清空上次依赖
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值