准备转Vue3, 看文档和一些文章时,看到ref(), 结合最近在用的Proxy,得出的结论就是:
ref()实际就是把传入的值对象或引用对象统一转换成Proxy对象,用于监听对象的变动,因为Proxy只支持引用对象,所以对于值对象, 会转换成{ value: 值 } 再转换成Proxy对象 此时就可以监听到value值的变化
Proxy介绍可以参见官网:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
目前Proxy的监听是单层的, new Proxy(obj) 只会把obj转成Proxy对象, obj内部的引用对象并不会转换, 所以obj.a的变动可以监测到, 而obj.a.b的变动就无法监测到了, 这个是刚使用Proxy时一个容易迷惑的点, 如果想要监听全部变动, 只需要递归把对象内多有的引用对象全部转成Proxy对象就可以了
然后最近使用Proxy造了个类似Vue watch的轮子, 使用方法如下
- 监听层数
import Watch, { watch, unWatch } from "@xpf0000/objectobserver"
let obj = { a: 0, b: { b0: 1 } }
obj = Watch(obj, 1)
let config = {
'*': {
handler(newVal, oldVal) {}
},
}
obj[watch](config)
obj.b.b0 = 2 //won't trigger
obj.a = 1 // trigger
obj.c = 0 // trigger
- deep
import Watch, { watch, unWatch } from "@xpf0000/objectobserver"
let obj = { a: 0, b: { b0: 1 } }
obj = Watch(obj)
let config = {
'b': {
handler(newVal, oldVal) {},
deep: false
},
}
obj[watch](config)
obj.b = { c: 0 } // trigger
obj.b.c = 1 //won't trigger if deep is false
- watch子属性
import {Watcher, watch, unWatch } from "@xpf0000/objectobserver"
let obj = { a: 0, b: { b0: 1 } }
obj = Watcher(obj)
watch(obj, {
'*': function(newVal, oldVal) {
}
})
watch(obj.a, {
'*': function(newVal, oldVal) {
}
})
watch(obj.b, {
'b0': function(newVal, oldVal) {
}
})
- unWatch
import {Watcher, watch, unWatch } from "@xpf0000/objectobserver"
let obj = { a: 0, b: { b0: 1 } }
obj = Watcher(obj)
let config = {
'*': function(newVal, oldVal) {
}
}
watch(obj, config)
unWatch(obj, config)
let watcher = watch(obj.a, config)
watcher.unWatch()
unWatch(obj) //移除全部监听
有感兴趣的可以看下:
https://github.com/xpf0000/ObjectObserver
有什么优化和建议可以提出来,大家共同探讨