【Vue源码】data响应式

本文介绍了Vue.js中响应式编程的核心——Observer和Watcher,展示了如何通过定义getter/setter实现数据监听,并结合Dep进行订阅发布。通过实例演示了如何在实际项目中应用这些原理来管理状态变化和视图更新。
摘要由CSDN通过智能技术生成
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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值