new一个Vue实例
new Vue({ template: ` <div> <span>{{text1}}</span> <span>{{text2}}</span> </div> `, data: { text1: ‘text1‘, text2: ‘text2‘, text3: ‘text3‘ } })
执行操作 this.text3="modify text3";
在多个Vue实例中用到同一个对象(全局对象)
let globalObj = { text1: ‘text1‘ }; let o1 = new Vue({ template: ` <div> <span>{{text1}}</span> </div> `, data: globalObj }); let o2 = new Vue({ template: ` <div> <span>{{text1}}</span> </div> `, data: globalObj });
执行操作globalObj.text1 = ‘hello text1‘;
形成数据与视图的一种对应关系
实现订阅者Dep:用来存放Watcher观察者对象
class Dep { constructor () { // 用来存放Watcher对象的数组 this.subs = []; } // 在subs中添加一个Watcher对象 addSub (sub) { this.subs.push(sub); } // 通知所有Watcher对象更新视图 notify () { this.subs.forEach(sub => { sub.update(); }) } }
class Watcher { constructor () { // 在new一个Watcher对象时将该对象赋值给Dep.target,在get中会用到 Dep.targer = this; } // 更新视图的方法 update () { console.log(‘视图更新啦~‘); } } Dep.target = null;
修改defineReactive以及Vue的构造函数
增加Dep类,用来收集Watcher对象
function defineReactive (obj, key, val) { // Dep类对象 const dep = new Dep(); Object.defineProperty(obj, key, { enumberable: true, configurable: true, get: function reactiveGetter () { // 将Dep.target(当前Watcher对象)存入dep的subs中 dep.addSubs(Dep.target); return val; }, set: function reactiveSetter (newVal) { if (newVal === val) return; // 在set时触发dep的notify来通知所有的Watcher对象更新视图 dep.notify(); } }) } ? class Vue { // Vue构造类 constructor (options) { this._data = options.data; // 新建一个Watcher观察者对象,此时Dep.target会指向这个Watcher对象 new Watcher(); // 模仿render的过程,为了触发test属性的get函数 console.log(‘render~‘, this._data.test) } }
在observer的过程会注册get方法,用来进行依赖收集
该闭包【observer】中会有一个Dep对象,用来存放Watcher对象的实例
Object.defineProperty 的set/get方法所处理的事情:
依赖收集的前提条件
触发get方法
新建一个Watcher对象
原文:https://www.cnblogs.com/pleaseAnswer/p/14331187.html