前言,由一个报错引发的思考
某天,星星君的控制台在星星君的奋笔疾Code之下出现了一个看起来很简单的报错
这个问题看起来很简单,大概意思是一些复杂类型设置为响应式会有性能的损耗,需要用 markraw 或者 shallowRef 使其变成浅引用(即非响应式)
但是向上追溯,问题就很奇怪了,星星君的export是这个样子的
如果没有记错,使用的地方其实就是将这个地方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!
这个API就是用来返回原始对象的,好的,了解用法了,继续往下看
好嘛,红框框部分完美踩坑。
shallowRef
哦,这个是变量单层转换,不会进行深度转换。
看起来好像不复杂的样子,那我们是不是可以顺便看一下源码膜拜一下大佬们怎么写代码的呢?
开搞!
深入
shallowRef
在reactive中找到shallowRef,进去之后看到shallowRef创建了一个Ref
如果是ref就return出来,不是则把变量变成ref
哇!有些简单欸!那我们猜猜看markRaw会不会是直接把存进去的变量return出来???
markRaw
同样的文件夹找到
实际上我们传入markRaw的有至少两种类型,reactive 和 普通对象,如果是普通对象,我们就可以直接return出去,如果是reactive也许我们可以解包?
大佬们写了个def的组件,继续下看
组合起来理一理,好嘛,什么return不return的,干脆直接在外面加个变量锁,如果有ReactiveFlags.SKIP,那我们就跳过处理。
涨姿势了ing!
今天就到这里思密达~