数据代理
对于vue的数据代理--》基于JS原生内置对象Object.defineProperty中的get与set方法--》let data = this._data = options.data; options是传入的形参(配置)this.$options = options
把data中所有的属性都代理到new出来的实例上。---相当于我们现在对vue实例的存取就是对data的存取
数据劫持
就是先对数据进行绑定到实例上,再进行存取回调函数的绑定(就是响应式)--》对实例属性在进行一次get、set函数(其中调用函数)
数据递归劫持
深度遍历数据属性
initData主要干了两件事:
- proxy函数对this._data进行代理,所以我们可以通过this.xxx访问到data的数据
- observe函数把data变成响应式
watcher
watch方法:就是传入属性值与回调函数,当属性发生改变时,执行回调函数。即用户可以动态的添加回调函数,所以一开始在get与set方法中就不能写死,就可以定义一个方法收集与执行回调函数。
底层代码如何实现的呢?
- 初始化watch配置中的所有属性(属性名,回调函数)<-->new Watcher对象
- $watch(key,cb),针对用户手动设置的回调函数<-->new Watcher对象
- 在Watcher对象中,依次遍历每个属性的回调函数,将其放入公共区间;
对于watcher的notify-->(1)遍历该属性上所有的回调函数,执行run的异步方法
(2)会将异步方法Promise.resolve().then(执行方法)放进任务队列watcherQueue中,如果任务中已经有该回调函数的id就不再推送。--一个watcherId(自增的方式)
存在问题一:对于watch的配置的确没有问题,但是如果新增一个属性,则是无法调用其中的属性的,因为watch配置中没有,就dep是没有该属性的回调函数
ans:通过$set属性绑定
插件的底层原理
由于vue/cli是由vue加上一些其他第三库形成的,就了解下插件的底层原理