React和Vue中监听变量变化的方法

2020-06-14 06:31:45易采站长站整理

// 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.