<script>
//创建依赖收集的类
export class Dep {
constructor() {
this.subs = []
}
//为添加依赖添加方法 我也不知道为什么要定义这个函数 直接写在depend不香么? 完成API? 或许有其他的用法
addSubs(sub) {
this.subs.push(sub)
}
//删除依赖 or 接触监听
removesubs() {
remove(this.subs, sub)
}
//添加依赖
depend() {
if (window.target) {
//判断全局中有咩有watcher绑定了window.target 有就收集
addSubs(window.target)
}
}
//发送通知到依赖 提醒依赖更新
notify() {
const subs = this.subs.slice() //或许是怕修改到原数组吧 因为slice方法不会影响到原数组
for (let i = 0; i < this.subs.length; i++) {
this.subs[i].update() //watcher中定义了update方法
}
}
}
//删除依赖
function remove(arr, item) {
if (arr.length) {
if (arr.indexOf(item) > -1) {
const index = Object.keys(arr)
arr.splice(index, 1)
}
}
}
//收集object中的全部子key 递归回调 创建Observer类 把全部都变成getter/setter的形式
export class Observer {
constructor(val) {
//判断是不是数组
if (!Array.isArray(val)) {
walk(val)
}
}
}
function walk(val) {
let keys = Object.keys(val)
for (let i = 0; i < val.length; i++) {
defineReactive(val, keys[i], val[keys[i]]) // 这里的val[keys[i] 是key中key 是为了判定key还有没有其他的对象
}
}
//订阅者watcher 也就是依赖
export class Watcher{
constructor(vm, expOrFn, cb) {
this.vm = vm;
this.cb = cb;
this.getter = parsePath(expOrFn) //获取data.a.b.c的内容
this.value = this.get(); // 当前值
}
get() { //获取当前的属性
window.target = this; //绑定当前目标
let val = this.getter.call(this.vm, this.vm) //把当前的路径放入这个watch对象中 获取当前数据
window.target = undefined;//取消为了下次获取
return val
}
update() {
//获取当前记录
let oldval = this.value;
//获取最新记录
let val = this.get()
//回调更新视图 //把this.cb的全部方法属性放到this.vm这个对象里 然后在把参数传进this.vm里
this.cb.call(this.vm, val, oldval)
}
}
//实现数据劫持和变化侦测
function defineReactive(data, key, val) {
if (typeof val === 'object') {
new Observer(val)
}
let dep = new Dep() //实例化类
Object.defineProperty(data, key, {
enumerable: true, //可以枚举
configurable: true, //可删除
get: function () {
//get不用传值 因为在收集到的依赖Watcher中绑定了window.target
//这里是收集依赖的
dep.depend() //在dep类中定义了depend方法
return val
},
set: function (newVal) {
//set要传newVal
if (val === newVal) {
return
}
val = newVal //更新新的newVal 不然会一直触发set(个人猜测)
dep.notify() //在dep类中定义了notify方法
},
})
}
</script>
vue实现双向数据绑定原理(数据劫持和发布订阅者)的个人理解注释
最新推荐文章于 2022-05-25 20:12:48 发布