美文网首页程序员
Vue3之ref()理解

Vue3之ref()理解

作者: 非常帅气的昵称吧 | 来源:发表于2021-01-22 00:18 被阅读0次

准备转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的轮子, 使用方法如下

  1. 监听层数
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
  1. 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
  1. 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) {
 }
})
  1. 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

有什么优化和建议可以提出来,大家共同探讨

相关文章

网友评论

    本文标题:Vue3之ref()理解

    本文链接:https://www.haomeiwen.com/subject/pxwjzktx.html