双向绑定原理--思路版

342 阅读2分钟

vue双向绑定

1.什么是双向绑定?view更新视图,试图更新view. 4个步骤实现双向绑定, 实现一个监听者,对象属性发生变化则通知订阅者。 实现一个订阅者 实现一个订阅者watcher,收到属性变化并执行对应方法,从而更新视图。

监听器Observer实现

实现一个监听者,属性发生变化通知并执行相应的方法。 Object.defineProperty()劫持对象的getter,setter方法. 例子:

Object.defineProperty(obj, prop, descriptor)

var person = { name: "wang" }

Object.defineProperty(person, 'name', {

get() {

console.log('name被读取了')

return 'zhao'

},

set(newVal) {

console.log('name属性被修改了...');

val = newVal;
}
})

我们通过 object.defineProperty() 方法给 person 的 name 属性定义了 get() 和set()进行拦截,每当该属性进行读或写操作的时候就会触发get()set() 

如果要监听对象的每一个属性的话,一个一个设太麻烦。需要进行封装。 封装就是封装对象key,然后循环对象每个属性进行调用那个封装方法。

vue3版本双向绑定

let data={value:0}

const vm=new Proxy(data,{

set:function(target,key,newValue){

console.log('被赋值为'+newValue)

return true

},

get:function(target,key){

console.log('被读取咯')

return target[key]

}

})

vue3proxy代理的优点是不需要进行递归对对象属性进行监听。

订阅器实现

订阅器的例子:ajax的回调函数 success,error,只要在回调函数订阅即可,不需要监听其他函数。

生活小栗子:老师布置作业,所有学生了解作业,不需要老师通知每个学生作业的内容。

Deps中每个notify方法,都会自行更新每个sub。sub就是订阅者。addSub:添加订阅者。notify:订阅者方法。

function Dep() {

this.deps = []

}

Dep.prototype - {

addSub: function () {

this.deps.push(sub)

},

notify: function () {

this.deps.forEach((dep) => {

dep.update()

})

}

}

Dep.target=null //释放资源

四订阅器Watcher实现

function watcher(vm,exp,cb)

{

this.vm=vm;

this.exp=exp;

this.cb=cb;

this.value=this.get();

}

watcher.prototype={

update:function(){

this.run()

},

run:function(){

var value=this.vm.data[this.exp]

var oldValue=this.value;

if(value!==oldValue){

this.value=value;

this.cb.call(this.vm,value,oldValue)

}

},

get:function(){

Dep.target=this// 全局变量,订阅者

var value=this.vm.data[this.exp];

Dep.target=null //全局变量,订阅者 释放

return value

}

}