一、实现双向绑定主要做了三件事
- 监听data(Observer),有变化就通知订阅者(Watcher)
- 订阅到了变化的data,将其和DOM节点结合起来,编译成一个 js对象,形成虚拟DOM(即源码中的document fragment)
- 所有变化都已对应完成,继而进行视图更新(即把 document fragment 变成实际的DOM树)
二、$nextTick
在执行响应式时,一个data的变化就创建一个Watcher,同一个Watcher被多次触发只记录一次,都被放入同个数组中,并且同一时间只能有一个watcher被计算(因为有个 Dep.target 表示当前正在计算的Watcher,是全局唯一的变量)。当所有变化都对应完,才进行视图更新。
那么当数据更新后马上就要操作DOM时,此时实际DOM树并没有发生改变,就会出错。所以可以使用$nextTick,实际是获取的更新后的DOM,也可以理解为等到实际DOM树被更新了才去操作DOM。
三、$set
双向绑定监听的是data() { return {} }里定义过的变量,若未定义而直接在方法里添加,是不能触发监听的。vue提供了$set实现双向绑定。
data() {
return {
student: {
name: 'Joe',
sex: 'male',
},
};
},
mounted() {
/*
@params this.student:要修改的对象
@params 'age':要添加的属性,必须是字符串
@params 24:属性的值
*/
this.$set(this.student, 'age', 24);
},