shallowReadonly 与 readonly原理浅析

Posted Bravo Jack

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shallowReadonly 与 readonly原理浅析相关的知识,希望对你有一定的参考价值。

vue3中的shallowreadonly与 readonly是怎么实现的呢?学习自[尚硅谷](https://24kcs.github.io/vue3_study/chapter4/03_手写组合API.html#_1-shallow readonly-%E4%B8%8E- readonly)

目的

使一个正常的object对象转化为响应式对象

解决方案

简单的说,就是w3c在object的增删改查时增加了hook函数,可以让用户对原生js获取事件、赋值事件等进行捕捉。这个hook函数就是ProxyReflect.
我接下来做的一件事就是使用这个hook函数,来使一个正常的object对象转化为响应式对象。

严格来讲,这个最后结果还不是响应式对象,只是这个object再增删改查属性的时候会触发自定义逻辑,具体编写什么样的逻辑能能够做到vue3中的响应式,本文没有阐述。

可以首先定义一个事件处理函数,对原生js获取事件、赋值事件等进行捕捉,随后再传递给Reflect

const readonlyHandler = {
  get (target, key) {
    if (key===\'_is_readonly\') return true

    return Reflect.get(target, key)
  },

  set () {
    console.warn(\'只读的, 不能修改\')
    return true
  },

  deleteProperty () {
    console.warn(\'只读的, 不能删除\')
    return true
  },
}

/* 
自定义shallowReadonly
*/
function shallowReadonly(obj) {
  return new Proxy(obj, readonlyHandler)
}

/* 
自定义readonly
*/
function readonly(target) {
  if (target && typeof target===\'object\') {
    if (target instanceof Array) { // 数组
      target.forEach((item, index) => {
        target[index] = readonly(item)
      })
    } else { // 对象
      Object.keys(target).forEach(key => {
        target[key] = readonly(target[key])
      })
    }
    const proxy = new Proxy(target, readonlyHandler)

    return proxy 
  }

  return target
}

/* 测试自定义readonly */
/* 测试自定义shallowReadonly */
const objReadOnly = readonly({
  a: {
    b: 1
  }
})
const objReadOnly2 = shallowReadonly({
  a: {
    b: 1
  }
})

objReadOnly.a = 1
objReadOnly.a.b = 2
objReadOnly2.a = 1
objReadOnly2.a.b = 2

以上是关于shallowReadonly 与 readonly原理浅析的主要内容,如果未能解决你的问题,请参考以下文章

vue3手写shallowReadonly浅只读

手写vue3源码——readonly, isReactive,isReadonly, shallowReadonly

手写vue3源码——readonly, isReactive,isReadonly, shallowReadonly

手写vue3源码——readonly, isReactive,isReadonly, shallowReadonly

Vue3.0源码剖析-响应式对象

Shell1