vue3的reactive模块梳理

1,372 阅读3分钟

先了解一下概念

主要是提供了这么几个对象

  • reactive
  • readonly
  • shallowReactive
  • shallowReadonly
  • markRaw 返回对象
  • toRaw 返回对象

然后提供了这么几个工具

  • isReactive
  • isReadonly
  • isProxy
  • markRaw
  • toRaw

首先理解他们之间的关系:

reactive and shallowReactive

reactive 可以响应数据,就是说getset都可以干一些事情的数据,是深响应,也就是说对标shallowReactive是浅响应,他俩的区别主要是浅响应只劫持一层。

reactive and toRaw

像这样

const obj = {}
const reactived = reactive(obj)
const row = toRaw(reactived)
// row === obj

也就是取响应的数据的原始数据

reactive and markRaw

标记一个对象,使其永远不会转换为响应数据,即不可代理的数据。

readonly and shallowReadonly

readonly 可以让一个响应数据只读,readonlyshallowReadonly的关系就象reactiveshallowReactive一样,他俩的区别主要是浅响应只劫持一层。

readonly and reactive

给出一段文档示例,除了不能set,其余的都一样

import { reactive, isReactive, readonly } from 'vue'
export default {
  setup() {
    const state = reactive({
      name: 'John'
    })
    // readonly proxy created from plain object
    const plain = readonly({
      name: 'Mary'
    })
    console.log(isReactive(plain)) // -> false

    // readonly proxy created from reactive proxy
    const stateCopy = readonly(state)
    console.log(isReactive(stateCopy)) // -> true
  }
}

readonly 普通对象

他就是不是一个响应对象

readonly 响应对象

他就是一个响应对象,并且响应对象改变,会触发readonly的监听,同样值可以变。这可能就是为什么叫readonly而不是disable

梳理逻辑

标记

其实这些对象都是响应或者不响应的对象,最重要的就是该不该响应和怎样响应的问题。

SKIP

带有这个标记的就是不应该响应的,如markRaw

IS_REACTIVE

带有这个标记的就是响应数据

IS_READONLY

带有这个标记的就是只读数据

RAW

这个不是标记,用于取原始对象,如toRow,但是并不一定是最原始的对象,如readonly的原始对象可能是响应对象。

REACTIVE

用于存放响应对象,也就是说如果该数据被响应过就直接返回结果

READONLY

同上,存放只读对象

工具函数

有了标记,思路就比较清晰了

isReactive

IS_REACTIVE标记的

isReadonly

IS_READONLY标记的

isProxy

IS_READONLY或者IS_REACTIVE标记的

markRaw

添加一个SKIP标记

toRaw

RAW存放的数据

公共部分与柯里化

前面提到重要的就是该不该响应和怎样响应的问题。所以要有一个可以决定该不该响应和怎样的响应的函数,在源码中是createReactiveObject还需要做决定返回什么样的对象。

检查数据

目标不是对象的

直接返回目标

目标已经处理过的

直接返回处理过的对象

对象不允许被响应的

返回对象本身

代理数据

不同的对象提供不同的getset

collectionHandlers

由 Object,Array,Map,Set,WeakMap,WeakSet 构造的

baseHandlers

上面取反

最后

在写wxue响应部分,看了@vue/reactivity的源码,并把他记录下来。顺便把reactive部分切换成@vue/reactivity,不再是重复造轮子,因为Vue3.x分包后更加独立。如果你想在小程序中体验Vue3.x的composition-api,赶快安装wxue试一试吧,如果可以的话点下star那就更完美了。