1 访问器属性是对象中的一种特殊属性,它不能直接在对象中设置,而必须通过Object.defineProperty() 方法单独定义。
2 极简双向绑定的实现
此例实现的效果是:随文本框输入文字的变化,div 中会同步显示相同的文字内容;在js或控制台显式的修改 obj.hello 的值,视图会相应更新。这样就实现了 model => view 以及 view => model 的双向绑定。
3 解析任务
上述示例仅仅是为了说明原理。我们最终要实现的是:
首先将该任务分成以下几部分:
1.输入框于文本节点跟data中的数据绑定 {
每次new一个vue,都调用了new selfVue函数,把el,data,methods,...作为一个对象当成参数传给selfVue函数,用Object.keys遍历data对象的每个属性,对其所有属性都进行监听,让他们成为访问器属性,都有getter和setter方法,同时会调用observe(this.data),就是为了初始化一个监听器,监听data中的数据,然后new Compile(options.el,this)就是初始化一个解析器,遍历其所有节点,判断是元素节点还是文本节点,如果是文本节点就直接编译,第一步初始化视图数据,第二步初始化一个订阅者(new Watcher()),并给订阅者绑定更新函数,然后订阅者就会把自己自动添加到订阅器中,如果是元素节点,就要区分具体是什么指令,解析这些指令,如果是事件指令就给他绑定事件,如果是v-model类似的指令,就给他绑定input事件,并且完成挂载,更新视图,同时初始化一个订阅者,并绑定更新函数
}
2.输入框内容变化时,data 中的数据同步变化。即 view => model 的变化{
修改输入框内容,在事件回调中修改属性值,(通过self.vm[exp]=newValue,触发selfVue中的setter去修改的)
}
3.data 中的数据变化时,文本节点的内容同步变化。即 model => view 的变化{
属性变了,就触发监听器里的setter,就会触发订阅器的dep.notify(),这个函数会遍历所有订阅者去更新,订阅者收到通知,就会执行绑定的更新函数
}