位置: IT常识 - 正文

讲讲vue3下会造成响应式丢失的情况

编辑:rootadmin
讲讲vue3下会造成响应式丢失的情况 题引:

推荐整理分享讲讲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下会造成响应式丢失的情况

我们一开始接触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的提问。

有需要的小伙伴,可以点击下方卡片领取,无偿分享

本文链接地址:https://www.jiuchutong.com/zhishi/299326.html 转载请保留说明!

上一篇:Conda常见命令总结(conda操作)

下一篇:【java web篇】MyBatis之Mapper代理(javaweb官方文档)

  • 毛利率在餐饮中表示什么意思?
  • 一般纳税人混凝土税率
  • 劳务服务公司不含派遣,能接外包吗
  • 营业外收入怎么结转到本年利润
  • 汇算清缴的利润表本期数与本年数
  • 简易计税项目税金要计入成本吗
  • 盘盈的固定资产计入什么科目
  • 住房租金专项附加扣除申报方式
  • 已认证发票退回的流程
  • 用友u8怎样查询上个月凭证
  • 公司将固定资产卖出,要交什么税
  • 多扣社保个人部分怎么做分录
  • 印花税股权转让计税依据
  • 装修增值税普通发票几个点
  • 建筑合同通用条款
  • 融资租赁购入固定资产开票吗
  • 外币业务汇兑损益根据业务划分为
  • 员工把发票丢了怎么处理
  • 企业所得税分期收款确认收入的时间政策
  • 土地增值税的土地成本要扣除增值税吗
  • 手机文件打开方式怎么设置默认
  • 劳务计提会计分录
  • 公司向法人借款有税务风险吗
  • 退款给客户怎么写分录
  • 装了win8以后不能上网
  • 房地产企业将开发产品抵押后再销售
  • windows7旗舰版为什么很多东西打不开
  • 股东变更需要哪些手续的法律规定
  • nodejs解压
  • 企业发给员工的工资要交税吗
  • 美国布莱斯大峡谷成因
  • 来料加工企业需注意什么
  • 股权激励费用摊销计算
  • 投标报名费怎么定
  • 迪纳利国家公园在哪个国家
  • 世界上最完美的犯罪
  • less变量
  • web 前端
  • 网上变更财务负责人
  • js array()
  • 新会计准则里的机械作业是什么
  • 资产减值损失属于什么科目
  • 外贸企业应交税费计入
  • sqlserver游标实例
  • 公积金个人缴纳和公司缴纳比例
  • 加班费是计入应交税费吗
  • 免费给人一些客户资料违法吗
  • 收到社会保险基金结算表
  • 一般纳税人主表中的25是怎么来的
  • 诉讼费用负担原则是什么
  • 固定资产的原价减去预计净残值后的余额
  • 出口免税项目
  • 什么是递延所得税?
  • 年度利润总额怎么填
  • mysql5.7.19 zip 详细安装过程和配置
  • SQL Server 2005/2008 用户数据库文件默认路径和默认备份路径修改方法
  • linux 命令帮助
  • win10临时文件设置
  • winex.exe - winex是什么进程
  • 如何禁止win10系统更新到win11
  • 快速解决便秘的小妙招
  • win10系统的电脑
  • cocos2dx吸蓝效果实现opengl绘制
  • 批处理书
  • unity 3d脚本编程
  • python将字典转换成字符串
  • nodejs基础知识
  • node.js tcp 服务器
  • listview控件设置多个列
  • android开发教程视频
  • django批量创建数据
  • python二分查找非递归
  • 公司在异地办公
  • 西藏拉萨工业园主要生产什么
  • 小额贷款公司在职人员和离职人员情节哪种轻
  • 有关单位和个人应该怎么样
  • 2021河南税务政策
  • 融资租赁公司购入老旧租赁资产会计处理
  • 资源税的计税方法
  • 财政部国家税务总局2021年40号
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设