Vue 3.0 上手(三)is 系列研究(isRef、isProxy、isReactive、isReadonly)

继续接上。之前在未正式发布前,自己就尝试对 is 系列进行研究,结果后来升级后,发生了不少变化,就决定正式版再说了。9月中下旬终于发布正式版,自己在节前终于抽空,把这部分补上。

isRef、isProxy、isReactive、isReadonly

之前测试 beta 时候的结果,但是升级 rc 后,发现部分结果不对了…所以最新修订了一版。在发布 3.0.0 后,又测试了下,和 rc 是一致的。

说明,下文的 ref(reactive) 之类的含义:

1
2
3
4
5
6
7
const refType = ref(0)
const computedType = computed(() => true)
const reactiveType = reactive({ foo: 'bar' })
const readonlyType = readonly({})

// ref(reactive) 等效于 ref(reactiveType)
// 其他原理相同

把所有的情况,都列举如来,测试如下(不考虑 markRaw 情况):

type isRef isReactive isReadonly isProxy
ref X X X
* ref(computed) X
* ref(reactive) X X X
* ref(readonly) X X X
computed X
* computed(ref) X
* computed(reactive) X
* computed(readonly) X
reactive X X
* reactive(ref) X X
* reactive(computed) X X
* reactive(readonly) X X
readonly X X
* readonly(ref) X
* readonly(computed) X
* readonly(reactive) X

对表格进行精简,如下:

type isRef isReactive isReadonly isProxy
ref X X X
* ref(computed) X
* ref(reactive) X X X
* ref(readonly) X X X
computed(any) X
reactive(any) X X
readonly X X
* readonly(ref) X
* readonly(computed) X
* readonly(reactive) X

表格结论

isReactive

Checks if an object is a reactive proxy created by reactive.

  • reactive 包裹的变量,一定是
  • readonly 只是特殊处理下,所以看包裹内的变量

isReadonly

Checks if an object is a readonly proxy created by readonly.

  • readonly 包裹的变量,一定是
  • computed 也是只读,也一定是
  • 还有就是一个特殊的,ref 包裹 computed,也是

isRef

Checks if a value is a ref object.

  • computed 是特殊的 ref
  • ref/computed 包裹的变量,一定是
  • readonly 只是特殊处理下,所以看包裹内的变量

isProxy

Checks if an object is a proxy created by reactive or readonly.

  • 只要是 isReactiveisReadonly 的,就是
  • 相当于 const isProxy = x => isReactive(x) || isReadonly(x)

总结

  • computed 变量,就是特殊的 ref
  • ref 变量,isRef 必定是 true
  • reactive 变量,isReactive 必定是 true
  • readonly 变量,isReadonly 必定是 true
  • readonly 就是包裹一层而已,不会影响内层变量的 isReactive isRef 判断
  • isProxy 是个方法集合,只要是 isReactiveisReadonly 的,isProxy 就是 true

没有特殊需求,不要反复嵌套。直接用基本的 reactive ref 基本类型就好。

isRef isProxy isReactive isReadonly 感觉日常用不到,没想到具体的应用场景。

–END–