方法执行时机
在beforeCreate之后,created之前,会initState
initState中会调用initData
源码分析
initData
上面代码主要做了三件事:
- 判断 data 对象的每一个 key,不可以和 props、methods 中的 key 相同。否则会报警告。可以看出优先级是 methods > props > data;
- 给data设置代理,代理vm._data到vm上,就可以通过this.xxx访问_data上的属性了;
- 观测data;
proxy
给data设置代理
data有个暗箱操作,就是访问转移,你用this.xxx访问data时,实际上访问的是this._data.xxx;
- 使用 data 在 vm 上占位,使得可以通过 vm.xxx 的形式访问到 data;
- 设置 Object.defineProperty的 get 和 set ,间接获取和赋值 vm._data,所有对 data的操作,转接到 vm._data 上;
observe
- 函数返回ob,ob就是Observer的实例,是通过data初始化的;
- data 必须是对象或数组;
- 如果 value 是数组或普通对象且可继承,则用它来初始化一个 Observer 实例;
- 如果 data 有__ob__属性,并且__ob_属性引用的是 Observer 的实例,则ob = value._ob;
- __ob__这个属性是在初始化 Observer 实例的时候加上的。有了这个属性就表示这个对象被观测过;
new Observer(value)这里面具体做了什么呢? 先看 constructor,做了几件事:
- 把 data 自身赋值到 observer 实例的 value 属性;
- 生成一个 dep 对象,赋值到 observer 实例的 dep 属性;
- 给自身添加一个__ob__属性,引用 observer 实例;
- 如果 value 是对象,就调用walk(value)方法遍历这个对象的属性;
- 如果 value 是数组,就调用observeArray(value)方法,观测数组的每个元素;
- 对于数组,需要拦截对数组的变异方法,当数组元素改变的时候,可以触发对应的依赖。protoAugment和copyAugment就是做这样的事。 observeArray(value)方法会遍历数组中的每一项,执行observe(items[i]),对每一项进行观测。 walk(value)方法遍历这个对象的属性,对每个属性调用defineReactive(obj, keys[i]),设置其 getter 和 setter 方法;
vue系列课程
最近会陆续的对vue进行源码分析,一系列课程如下: