本文最后更新于 253 天前,如有失效请评论区留言。
监听更新
本质
let a = 3
let b = a * 10
a = 4
console.log(b)
定义一个a、b,想让b永远跟随a的改变而改变,输出40,所以就需要监听a的变化,每当a变化的时候,就取出b的表达式重新执行一遍,这样就能保证a改变了b也改变
简单实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
<script>
let activeEffect
class Dep {
constructor(value) {
this.subscribers = new Set()
this._value = value
}
get value () {
this.depend()
return this._value
}
set value (newValue) {
this._value = newValue
this.notify()
}
depend () {
if (activeEffect) {
this.subscribers.add(activeEffect)
}
}
notify (effect) {
this.subscribers.forEach(effect => {
effect()
})
}
}
function watchEffect (effect) {
activeEffect = effect
effect()
activeEffect = null
}
const a = new Dep('3')
let b = 0
watchEffect(() => {
b = a.value * 10
console.log(b);
})
a.value = '4'
</script>
</html>
这里定义了一个Dep类去监听a的变化,然后通过watchEffect去更新b的值,这样每次更改a后b的值也能随之更改
具体就是通过get方法监听 a.value 获取值的时候把 watchEffect传入的函数保存到Dep类的subscribers的set无序集合中(当然也可以是数组,set只是个小优化虽然一般情况下可能用不上,只有两个相同的函数传入watchEffect时才会优化),然后再通过set监听a.value的赋值改动,变化值后及时调用watchEffect中传入的数组,达到更新的目的