Vue双向榜单的原理
大家都知道Vue采用的是MVVM的设计模式,采用数据驱动实现双向绑定,不明白双向绑定原理的需要先补充双向绑定的知识,在watch的处理中将运用到Vue的双向榜单原理,所以再次回顾一下:
Vue的数据通过Object.defineProperty
设置对象的get和set实现对象属性的获取,vue的data下的数据对应唯一 一个dep对象,dep对象会存储改属性对应的watcher,在获取数据(get)的时候为相关属性添加具有对应处理函数的watcher,在设置属性的时候,触发def对象下watcher执行相关的逻辑
// 为data的的所有属性添加getter 和 setterfunction defineReactive( obj,key,val,customSetter,shallow) { // var dep = new Dep(); /*....省略部分....*/ var childOb = !shallow && observe(val); //为对象添加备份依赖dep Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter() { var value = getter ? getter.call(obj) : val; if (Dep.target) { dep.depend(); // if (childOb) { childOb.dep.depend(); //依赖dep 添加watcher 用于set ,array改变等使用 if (Array.isArray(value)) { dependArray(value); } } } return value }, set: function reactiveSetter(newVal) { var value = getter ? getter.call(obj) : val; /* eslint-disable no-self-compare */ if (newVal === value || (newVal !== newVal && value !== value)) { return } /* eslint-enable no-self-compare */ if ("development" !== 'production' && customSetter) { customSetter(); } if (setter) { setter.call(obj, newVal); } else { val = newVal; } childOb = !shallow && observe(newVal); dep.notify();//有改变触发watcher进行更新 } });}
在vue进行实例化的时候,将调用 initWatch(vm, opts.watch);进行初始化watch的初始化,该函数最终将调用 vm.$watch
(expOrFn, handler, options) 进行watch的配置,下面我们将讲解 vm.$watch方法
Vue.prototype.$watch = function ( expOrFn, cb, options ) { var vm = this; if (isPlainObject(cb)) { return createWatcher(vm, expOrFn, cb, options) } options = options || {}; options.user = true; //为需要观察的 expOrFn 添加watcher ,expOrFn的值有改变时执行cb, //在watcher的实例化的过程中会对expOrFn进行解析,并为expOrFn涉及到的data数据下的def添加该watcher var watcher = new Watcher(vm, expOrFn, cb, options); //immediate==true 立即执行watch handler if (options.immediate) { cb.call(vm, watcher.value); } //取消观察函数 return function unwatchFn() { watcher.teardown(); } };
来看看实例化watcher的过程中(只分享是观察函数中的实例的watcher)
新闻热点
疑难解答
图片精选