模拟vue数据劫持实现发布订阅核心代码
// 定义一个依赖收集器 class Dep { constructor() { this.subs = [] // 订阅者列表 } // 添加订阅者 addSub(sub) { this.subs.push(sub) } // 通知所有订阅者数据已更新 notify() { this.subs.forEach(sub => sub.update()) } } // 定义一个观察者 class Watcher { constructor(vm, exp, cb) { this.vm = vm this.exp = exp this.cb = cb this.value = this.get() // 初始化值 } // 获取当前值 get() { Dep.target = this // 将当前订阅者指向该自身 let value = this.vm[this.exp] // 获取当前值,并触发依赖收集 Dep.target = null // 收集完毕后,将订阅者置空 return value } // 当被依赖的数据更新时,触发更新回调 update() { let value = this.vm[this.exp] if (value !== this.value) { this.cb.call(this.vm, value, this.value) this.value = value } } } // 数据劫持函数 function observe(obj, vm) { if (!obj || typeof obj !== 'object') { return } Object.keys(obj).forEach(key => { defineReactive(vm, key, obj[key]) }) } // 定义一个数据劫持函数 function defineReactive(vm, key, val) { let dep = new Dep() // 定义依赖收集器 Object.defineProperty(vm, key, { get() { if (Dep.target) { dep.addSub(Dep.target) // 添加订阅者 } return val }, set(newVal) { if (newVal === val) { return } val = newVal dep.notify() // 数据更新,通知所有订阅者 } }) }
以上代码中,Dep类是依赖收集器,Watcher类是观察者,defineReactive函数是数据劫持函数。在数据劫持过程中,会监听对象的属性的变化,一旦有变化会触发数据改变的通知,通知所有已经订阅当前值的订阅者进行数据更新。同时,也提供了添加订阅者和通知订阅者更新的接口。
以上就是模拟vue数据劫持实现发布订阅核心代码全部内容,感谢大家支持自学php网。