function reactive(obj) {
const proxy = new Proxy(obj, {
get(target, key) {
/*
render函数第一次渲染的时候会获取引用的值 所以第一次渲染就会走到这个 get 方便我们开始做依赖收集
*/
track(target, key)
return target[key]
},
set(target, key, value) {
target[key] = value
console.log(‘proxy’, key)
/*
修改的时候,去依赖收集的数据结构中 找到对应的key 把 key 对应的 更新函数都执行一遍,这就触发了页面的响应式
*/
trigger(target, key)
// app.update()
}
/*
proxy 的优势出了可以监听get 和 set之外 还是可以监听另外十多种情况,这个是Object.defineProperty()做不到的
这个是语言层面上的升级
*/
})
return proxy
}
// 副作用函数 – 这里是为了暂时的存放每一个副作用函数,当副作用函数已经和依赖关系建立好了之后再清除空间
const effectStack = []
function effect(fn) {
const eff = function () {
try {
effectStack.push(eff)
fn()
} finally {
effectStack.pop()
}
}
eff()
return eff
}
// 依赖收集函数
/*
依赖收集的数据结构是这样的
{
state:{
title:[effect,effect] // effect 对应的就是一个个的更新函数,每个响应式对象的值都是存着更新函数的数组,当这个值变化的时候遍历执行数组里面的一个个effect函数
}
}
*/
const trackMap = {}
function track(target, key) {
/*
effectStack 是临时存放副作用函数的地方,每次关系建立完成之后就会再清空掉,所以获取数组的最后一个元素即可
*/
const effect = effectStack[effectStack.length - 1]
if (effect) {
let map = trackMap[target]
if (!map) {
map = trackMap[target] = {}
}
let deps = map[key]
if (!deps) {
deps = map[key] = []
}
// 将副作用函数放入 deps
if (deps.indexOf(effect)