const toProxy = new WeakMap() // 存放的是 代理后的对象
const toRaw = new WeakMap() // 存放的是 代理前的对象
function trigger() {
console.log('触发视图更新')
}
function isObject(target) {
return typeof target === 'object' && target !== null
}
function reactive(target) {
if (!isObject(target)) {
return target
}
// 若代理表中已经存在了, 就直接返回
let proxy = toProxy.get(target)
if (proxy) {
return proxy
}
// 若这个对象已经被代理过的,就直接返回
if (toRaw.get(target)) {
return target
}
const handles = {
set(target, key, value, receiver) {
// 如果触发的是私有属性,直接触发更新
if (target.hasOwnProperty(key)) {
trigger()
}
return Reflect.set(target, key, value, receiver)
},
get(target, key, receiver) {
const res = Reflect.get(target, key, receiver)
// 若属性仍是对象,继续代理
if (isObject(target[key])) {
return reactive(res)
}
return res
},
deleteProperty(target, key) {
return Reflect.deleteProperty(target, key)
}
}
let observed = new Proxy(target, handles)
toProxy.set(target, observed)
toRaw.set(observed, target)
return observed
}
let obj = {
name: '666',
a: [1, 2, 3]
}
let p = reactive(obj)
p = reactive(p)
p = reactive(p)
p = reactive(p)
p.name = '777'
p.a.push(4)
console.log(p)
手写简易vue3响应式reactive
最新推荐文章于 2025-05-11 17:23:59 发布