【Vue源码】data响应式

class Observer{ // 响应式处理器
  constructor(data){
    this.data = data
    if(!Array.isArray(data)) this.walk(data)
  }
  walk(data){
    for(let key in data){
      defineReactive(data,key,data[key])
    }
  }
}
function defineReactive(data,key,value) { // 响应式
  if(typeof value ==='object') new Observer(value)

  let dep = new Dep()
  Object.defineProperty(data,key,{
    enumerable:true,
    configurable:true,
    get(){
      dep.depend()
      return value
    },
    set(newValue){
      if(value===newValue) return
      value = newValue
      dep.notify()
    }
  })
}

class Watcher{ // 观察者
  constructor(vm,exp,cb){
    this.vm = vm
    this.getter = parsePath(exp)
    this.value = this.get()
    this.cb = cb
  }
  get(){
    window.target = this
    let value = this.getter.call(this.vm,this.vm)
    window.target = undefined
    return value
  }
  update(){
    let oldValue = this.value
    this.value = this.get()
    this.cb&&this.cb.call(this.vm,this.value,oldValue)
  }
}

function parsePath(exp) {
  if(/[^\w.$]/.test(exp)) return

  let segments = exp.split('.')
  return (obj)=>{
    for(let key of segments){
      obj = obj[key]
    }
    return obj
  }
}

class Dep{ // 发布订阅者
  constructor(){
    this.deps = []
  }
  depend(){
    if(window.target) this.addSub(window.target)
  }
  addSub(sub){
    this.deps.push(sub)
  }
  notify(){
    for(let watcher of this.deps){
      watcher.update()
    }
  }
}
let vm = new Vue({
  data(){
	return{
	  list:[...]
	}
  }
})
new Observer(vm.$data)
new Watcher(vm,$data.list,fn)


1.状态data经过响应式处理器Observer设置成getter/setter
2.Watcher作为状态的观察者,View通过watcher.get()获取vm内部状态并渲染的同时会将watcher挂载到window.target,同时会触发状态的getter从而通过dep.depend()watcher订阅进依赖列表deps
3.Dep作为watcher的订阅发布者,在状态getter时将watcher订阅进deps,在状态改变setter时,通过dep.notify()从deps取出订阅的watcher并通过watcher.update()通知其更改观察的状态并重新渲染view

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值