响应式入口
src / core / instance / state.js;
function initState(vm) {
const opts = vm.$options;
if (opts.props) initProps(vm, opts.props);
if (opts.methods) initMethods(vm, opts.methods);
if (opts.data) {
initData(vm);
} else {
observe((vm._data = {}), true /* asRootData */);
}
if (opts.computed) initComputed(vm, opts.computed);
if (opts.watch && opts.watch !== nativeWatch) {
initWatch(vm, opts.watch);
}
}
- 通过上面initState函数得知 props,methods,data的顺序
props、methods、data、computed、watch
initData
let data = vm.$options.data;
observe(data);
响应式处理
// src/core/observer/index.js
function observe(value) {
new Observe(value);
}
class Observe {
constructor(value) {
this.value = value;
// 数组处理
if (Array.isArray(value)) {
if (hasProto) {
protoAugment(value, arrayMethods);
} else {
copyAugment(value, arrayMethods, arrayKeys);
}
} else {
// 对象处理
this.walk(value);
}
}
walk(obj) {
const keys = Object.keys(obj);
for (let i = 0; i < keys.length; i++) {
defineReactive(obj, keys[i]);
}
}
}
响应式核心函数
function defineReactive(obj, key) {
const dep = new Dep(); // 每一个key对应一个Dep实例
let childOb = observe(val); // 递归遍历对象嵌套
Object.defineProperty(obj, key, {
get() {
// obj上是否存在自定义get,如果没有则取obj[key]
const value = getter ? getter.call(obj) : obj[key];
if (Dep.target) {
dep.depend(); // 依赖收集
if (childOb) {
childOb.dep.depend(); // 子依赖收集
if (Array.isArray(value)) {
dependArray(value); // 处理数组依赖
}
}
}
return value;
},
});
}
Dep
// src/core/observer/dep.js
class Dep {
constructor() {
this.subs = []
}
addSub(sub) {
this.subs.push(sub)
}
depend() {
if (Dep.target) {
Dep.target.addDep(this)
// 1. defineReactive执行depend里却调用了watcher的addDep,
// 2. 在addDep中把dep保存到watcher里(this.newDeps.push(dep))
// 3. 然后又调用了dep.addSub(this)把watcher保存到dep中,实在是骚的一批
}
}
}
Dep.target = null
const targetStack = [] // 保存的是watcher
// 在watcher中调用pushTarget
export function pushTarget (target: ?Watcher) {
targetStack.push(target)
Dep.target = target // target为watcher实例,在上面defineReactive中通过dep.depend()把watcher收集到dep中
}