vue响应式ui(讲讲vue3下会造成响应式丢失的情况)
题引:
在我们从vue2过渡到vue3的时候 ,对于数据响应式的变化其实是懵懵懂懂的 。从以往直接在data函数里面定义变量到每一次都要使用ref/reactive时 ,是有些不适应的 。但问题不大 ,毕竟在大前端时代中 ,如果不及时跟上时代的步伐 ,不仅技术没跟上 ,面试还容易被卡 。所以今天来聊聊在使用vue3开发时对于数据响应式的理解 。
vue3的响应式是基于 proxy
从vue2的 Object.defineProperty 到vue3的 proxy 可谓是一个质的飞跃 。vue2的响应式是需要递归+遍历每一个对象的属性进行数据劫持 ,而在vue3中只需要对对象层进行监听即可 。好了话不多说 ,开始讲解一些常见的响应式问题 。
ref和reactive之间的关系
如果我们用ref定义基本类型时 ,实际上还是使用 Object.defineProperty 进行数据劫持监听 。但如果是定义引用类型时 ,底层代码上是借用 reactive 函数进行数据劫持的 。因此ref和reactive关系是紧凑的 。通过源码的我们是可以确认的 。
我们可以看到 ,this_value = useDirectValue ? newVal : toReactive(newVal) 是进行了判断 ,而 useDirectValue 是进行判断是否是浅层的 、仅可读的数据 。 那么如果我们传入的是一个对象,那么就会进入 toReactive(newVal) 这一步。 toReactive 函数就是进行reactive定义的函数入口 。
reactive定义的变量重新赋值会失去响应式 ,而ref不会
我们一开始接触vue3的时候 ,会对这个问题十分的不解,只是知道有这个问题而不知其根 ,今天就来讲讲这个问题 。
import {ref,reactive} from vue; let test = {age:2}; let obj = reactive({age:1}) let obj1 = ref({age:1}) obj = test; obj1.value = test;通过reactive()包含的对象是进行了内部的proxy代理 ,因此具有响应式。但是像test这个对象 ,它是没有进行数据劫持的 ,而对象赋值的时候实际上是引用地址赋值 。那么obj这个对象变成了一个没有数据劫持的引用地址 ,那么它也就失去了响应式 。但是obj1重新赋值时会保留自身的响应式 。其实很简单 ,跟上图的代码是有关的 。细心的人会发现 ,在 set 函数里面有这么一段代码 。
是的 ,在我们对ref定义的变量重新赋值时会进入 set 函数 ,且重新赋值的是一个对象的话 ,那么它会再次进入 toReactive 函数进行数据劫持 ,这就是为什么ref定义的变量重新赋值对象时依旧保留响应式的根本原因 。
解构响应式对象会造成响应式丢失
通过上面我都知道 ,不管是ref还是reactive定义的对象变量,都会经过 reactive 函数来进行proxy代理 。但是即使是对象 ,也会出现响应式丢失的情况 。
<script setup> import {reactive,onMounted} from vue; let obj = {a:18,aa:{age:18},aaa:{friend:{age:18}} } let rect = reactive(obj); let {a,aa,aaa} = rect; onMounted(()=>{setTimeout(()=>{a = 2;aa.age = 2;aaa.friend.age = 2;},2000) }) </script> <template><div>{{a}}</div><div>{{aa.age}}</div><div>{{aaa.friend.age}}</div> </template>上面的运行结果就是 ,a变量没有响应式,aa和aaa都是响应式 。这是因为在解构赋值中 ,如果是原始类型的话是按照值传递 ,如果是引用类型的话是按照引用地址传递 。除此之外 reactive() 定义的变量中 get函数 有这样的一个处理
a = rect.a; //rect.a是一个基本类型 ,所以是直接赋值 aa = rect.aa; //rect.aa是一个引用类型 ,在内部处理时触发条件判断 ,且非可读对象即从Map数据结构中返回已经代理的响应式对象 aaa = rect.aaa //跟rect.aa一个道理因此以后对响应式对象进行解构时 ,记住以上的内部判断逻辑就可以拿捏它们了(#.#) 。当然 ,对vuex或者pinia的取值也是这个道理 ,也就是为什么需要借助 computed() 来实现响应式了 。因此 computed() 能返回响应式。
最后
整理了75个JS高频面试题 ,并给出了答案和解析 ,基本上可以保证你能应付面试官关于JS的提问 。
有需要的小伙伴 ,可以点击下方卡片领取 ,无偿分享
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!