森泥.酷哦

加油,小可耐!

Vue中的观察者模式

框架 设计模式 0 评 75 度
观察者模式定义了一种一对多的依赖关系,,让多个观察者对象同时监听某一个目标对象,当这个目标对象的状态发生变化时,会通知所有观察者对象,使它们能够自动更新。

Vue响应式系统实现原理

observer:是数据监听器也是发布者

Dep:用于收集订阅者和通知订阅者

watcher:真实的订阅者,收到数据更新去更新视图

complie:编译器,负责指令解析,创建订阅者等

// 简单模拟只考虑对象
class Dep {
  static target = null
  constructor(){
    // 初始化订阅队列
    this.subs = []
  }
  // 添加订阅者
  addSub(sub) {
    this.subs.push(sub)
  }
  // 给当前目标对象添加订阅者
  depend() {
    console.log("添加订阅者")
    if (Dep.target) {
      Dep.target.addDep(this)
    }
  }
  // 通知订阅者
  notify() {
    console.log("通知更新")
    console.log(this.subs)
    this.subs.forEach(sub=>{
      sub.update()
    })
  }
}
function Observer(data) {
  if(data && typeof data === 'object') {
    Object.keys(data).forEach(key=>{
      // 给目标属性添加上数据监听器
      defineReactive(data,key,data[key])
    })
  }
}
function defineReactive(data,key,val) {
  // 如果属性值也是对象,递归属性值给加上监听器
  Observer(val)
  const dep = new Dep()
  Object.defineProperty(data,key,{
    get:function(val){
      // 绑定订阅者
      if (Dep.target) {
       dep.depend()
      }
      return val
    },
    set:function(value){
      // 通知订阅者
      dep.notify()
      val = value
    }
  })
}
class Watcher {
  constructor(){
     this.get()
  }
  // 获取当前监听器
  get () {
    console.log("创建订阅者")
    Dep.target = this
  }
  // 添加
  addDep(dep){
    dep.addSub(this)
    console.log(dep,'添加依赖')
  }
  // 更新操作
  update(){
    console.log('更新视图')
  }
}
let a = {b:1}
Observer(a) // 初始化响应式数据
new Watcher()
a.b // 触发依赖收集
a.b = 2 // 触发更新机制

// 创建订阅者
// 添加订阅者
// Dep { subs: [ Watcher {} ] } 添加依赖
// 通知更新
// [ Watcher {} ]
// 更新视图
Vuex 阅读