console
// const $app1 = document.querySelector('#app1')
// const $app2 = document.querySelector('#app2')
// const state = {
// text: 'hello fatfish',
// text2: 'hello fatfish2'
// }
// // 改变app1的值
// function effect1() {
// console.log('执行了effect')
// $app1.innerText = state.text
// }
// // 改变app2的值
// function effect2() {
// console.log('执行了effect2')
// $app2.innerText = state.text2
// }
// // 1秒钟之后两个div的值要分别改变
// setTimeout(() => {
// state.text = 'hello Vue3'
// state.text2 = 'hello Vue3-2'
// }, 1000)
// 应该把effect依赖函数通过某种机制,主动注册到桶中,这样无论你是匿名函数亦或者是具名函数都一视同仁
const $app1 = document.querySelector('#app1')
const $app2 = document.querySelector('#app2')
let activeEffect;
// 通过effect函数去主动收集依赖
const effect = function (fn) {
console.log(fn)
// 每执行一次,将当前fn赋值给activeEffect,这样在fn中触发读取操作时,就可以被收集进bucket中
activeEffect = fn
// fn需要主动执行一次,必不可少
fn()
}
const bucket = new Set()
const state = new Proxy({ text1: 'hello text1', text2: 'hello text2' }, {
get(target, key) {
const value = target[key]
// 第一步:收集依赖,在读取key时,将effect函数存储起来
bucket.add(activeEffect)
console.log(`get${key}:${value}`)
return value
},
set(target, key, newValue) {
console.log(`set${key}:${newValue}`)
target[key] = newValue
// 第二步:设置值时,将依赖执行
bucket.forEach((fn) => fn())
}
})
effect(function effect1() {
console.log('执行了effect1')
$app1.innerText = state.text1
})
effect(function effect2() {
console.log('执行了effect2')
$app2.innerText = state.text2
})
setTimeout(() => {
state.text1 = 'hello xuqiushi---1'
state.text2 = 'hello xuqiushi---2'
}, 2000)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="app1"></div>
<div id="app2"></div>
</body>
</html>
#app1{
width: 200px;
height: 100px;
background-color: #ffffff;
}
#app2{
width: 200px;
height: 100px;
background-color: lightcyan;
}