敲黑板,你分的清Vue3中哪些是响应式么?

前言,由一个报错引发的思考

某天,星星君的控制台在星星君的奋笔疾Code之下出现了一个看起来很简单的报错

image.png

这个问题看起来很简单,大概意思是一些复杂类型设置为响应式会有性能的损耗,需要用 markraw 或者 shallowRef 使其变成浅引用(即非响应式)

但是向上追溯,问题就很奇怪了,星星君的export是这个样子的

image.png

如果没有记错,使用的地方其实就是将这个地方import进去,那么他提示这里是响应式,十分不合理啊!

接下来就出现了两种可能,1. 在VUE3中导出的也是响应式 2. 代码中哪里出现了问题

template在被处理的时候,会经过proxy么???第一反应是,这不合理,但是又没有研究过,那就先从第二个部分入手叭,查看代码应用的地方

使用的是 <component :is=“import.component”></component>

好像没问题,难道is会进行转换???咦,不对,[import] 这个变量,为什么不是我import进来那个变量的名字呢???然后星星君在代码中看到了一个骚操作

import aa from default

const import = ref(aa)

好嘛大兄die,解迷了,转换完他要不是reactive那才是出大事故了!

问题解决了,我们也知道导出并不会让我们的组件变成响应式,只有reactive和ref大法才可以,那么又出现了下一个问题,markRaw 和 shallowRef 你造么??

星星君决定再去翻一下官方文档,以及深入了解一下这两个API

markRaw

官方文档YYDS!

image.png

这个API就是用来返回原始对象的,好的,了解用法了,继续往下看

image.png

好嘛,红框框部分完美踩坑。

shallowRef

image.png

哦,这个是变量单层转换,不会进行深度转换。

看起来好像不复杂的样子,那我们是不是可以顺便看一下源码膜拜一下大佬们怎么写代码的呢?

开搞!

深入

shallowRef

在reactive中找到shallowRef,进去之后看到shallowRef创建了一个Ref

image.png

image.png

如果是ref就return出来,不是则把变量变成ref

哇!有些简单欸!那我们猜猜看markRaw会不会是直接把存进去的变量return出来???

markRaw

同样的文件夹找到

image.png

实际上我们传入markRaw的有至少两种类型,reactive 和 普通对象,如果是普通对象,我们就可以直接return出去,如果是reactive也许我们可以解包?

大佬们写了个def的组件,继续下看

image.png

组合起来理一理,好嘛,什么return不return的,干脆直接在外面加个变量锁,如果有ReactiveFlags.SKIP,那我们就跳过处理。

涨姿势了ing!

今天就到这里思密达~

猜你喜欢

转载自juejin.im/post/7113022337028456461