Vue是通过数据监听结合发布-订阅模式完成数据驱动视图的响应式原理。
-
文字描述:
创建Vue实例,通过观察者observer方法给data上的每一个属性,包括对象属性通过object.defineproperty方法增加get和set方法,并且创建dep实例-依赖收集器,dep实力上有添加订阅和通知方法,get增加订阅,set通知订阅修改值,数据和视图响应关系的建立通过watcher,compile解析dom,解析指令,每使用一次data上的值就产生一个对应的watcher,存储当前的值并添加依赖收集,收集所有的watcher,当属性值有更改,遍历所有watcher,update新值。
-
文字描述2: 实例化vue,将vue的data属性传入observer方法,通过深度递归遍历,拿到所有的属性,通过object.defineproperty添加set,和get方法实现监听data上的每一个属性,通过订阅者和发布者模式,获取值时收集使用属性的依赖,和设置值时统一通知发布订阅,这其中有一个watcher类来实现依赖,当解析dom中的指令时会生成使用属性的对应的watcher实例,并在watcher内部给Dep.target赋值,在订阅的时候将Dep.target收集起来,并在订阅后将dep.target清空,防止其他属性第一次初始化收集错误依赖。
-
代码:(不全,只是自己的思路)
var vm = new vue({
el:"#app",
data:msg,
methods:{
fn(){
this.msg = '123';
}
}
})
class Vue {
constructor(option={}){
this.$data = option.data;
this.$vm = this,
this.$el = option.el,
new observer(this)
}
}
class observer {
constructor(vm){
this.walk(vm)
}
walk(vm){
Object.keys(vm).forEach(function(key){
this.definePro(data,key)
})
}
definePro(obj,key){
let dep = new Dep();
Object.defineproperty(obj,key,{
enumrable:true,
configurable:true,
set:function(newvalue){
dep.notify()
value = newvalue
},
get:function(){
Dep.target&&dep.addsub(Dep.target)
return value
}
})
}
}
class compile {
constructor(vm){
this.$vm = vm;
}
<!--解析指令-->
node.context = this.getvalue();
new watch(vm,节点所用属性,(newvalue)={
node.context = newvalue
})
}
class watch {
constructor(vm,cb){
this.cb = cb;
Dep.target = this;
this.oldvalue = this.getvalue()
}
updte(){
if(this.oldvalue != newvalue){
this.cb(newvalue)
}
}
getDataValue(){
}
}
class dep {
constructor(){
this.subs = [];
}
addsub(watcher){
this.subs.push(watcher)
}
notify(){
this.subs.forEach((sub){
sub.updte()
})
}
}
复制代码