// base state.
var updateQueue = workInProgress.updateQueue;
if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
updateQueue.baseState = memoizedState;
}
}
Vue
vue监听变量变化依靠的是 watch ,因此我们先从源码中看看, watch 是在哪里触发的。
Watch触发条件
在 src/core/instance 中有 initState()
/core/instance/state.js
在数据初始化时 initData() ,会将每vue的data注册到 objerserver 中
function initData (vm: Component) {
// ...省略部分代码 // observe data
observe(data, true /* asRootData */)
}
/**
* Attempt to create an observer instance for a value,
* returns the new observer if successfully observed,
* or the existing observer if the value already has one.
*/
export function observe (value: any, asRootData: ?boolean): Observer | void {
if (!isObject(value) || value instanceof VNode) {
return
}
let ob: Observer | void
if (hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {
ob = value.__ob__
} else if (
shouldObserve &&
!isServerRendering() &&
(Array.isArray(value) || isPlainObject(value)) &&
Object.isExtensible(value) &&
!value._isVue
) {
// 创建observer
ob = new Observer(value)
}
if (asRootData && ob) {
ob.vmCount++
}
return ob
}
来看下 observer 的构造方法,不管是array还是obj,他们最终都会调用的是 this.walk()
constructor (value: any) {
this.value = value
this.dep = new Dep()
this.vmCount = 0
def(value, '__ob__', this)
if (Array.isArray(value)) {
const augment = hasProto
? protoAugment
: copyAugment
augment(value, arrayMethods, arrayKeys)
// 遍历array中的每个值,然后调用walk
this.observeArray(value)
} else {
this.walk(value)
}
}我们再来看下walk方法,walk方法就是将object中的执行 defineReactive() 方法,而这个方法实际就是改写 set 和 get 方法
/**
* Walk through each property and convert them into
* getter/setters. This method should only be called when
* value type is Object.
*/
walk (obj: Object) {
const keys = Object.keys(obj)
for (let i = 0; i < keys.length; i++) {
defineReactive(obj, keys[i])
}
}
/core/observer/index.js
defineReactive 方法最为核心,它将set和get方法改写,如果我们重新对变量进行赋值,那么会判断变量的新值是否等于旧值,如果不相等,则会触发 dep.notify() 从而回调watch中的方法。
/**
* Define a reactive property on an Object.










