位置: IT常识 - 正文

vue 计算属性未重新计算 / computed 未触发 / computed 原理&源码分析(vue3 计算属性)

编辑:rootadmin
vue 计算属性未重新计算 / computed 未触发 / computed 原理&源码分析

推荐整理分享vue 计算属性未重新计算 / computed 未触发 / computed 原理&源码分析(vue3 计算属性),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:vue2计算属性,vue计算属性不触发,vue2计算属性,vue3 计算属性,vue中的计算属性可以有参数吗,vue计算属性setter,vue使用计算属性,vue使用计算属性,内容如对您有帮助,希望把文章链接给更多的朋友!

点击可打开demo 这里在一秒后改了数组里value属性的值 虽然数据有更新,但打开控制台,可以发现computed函数只在初始化时执行了一次 按理说一秒后改变了value值,应该执行两次才对呀? 但如果computed属性这样写,明确写明展开了每一项,获取到了value属性,就能执行第二次 vue的文档里提到,计算属性的方法只应该有单纯的计算,不要产生其他效果,像我们上面的demo,虽然数据有更新,但console.log没打印,这里的console.log其实就算是文档里的side effects 为什么会有这种表现呢?

看看vue的源码吧!顺便学习一下computed是如何实现的!

这里先说整体思路 这里用了proxy,对所有响应式对象加proxy,这样就能改他们的get和set等方法,然后当读取计算属性时,执行computed里的方法,执行的时候,会读取到其依赖的响应式对象,因为之前改了他们的set方法,所以此时能知道读取的是哪个对象的什么属性,此时就能把他加到computed属性的依赖中。但依赖的值发生改变,因为用proxy改过其get方法,同时之前收集过依赖,知道这个依赖值被哪些值所依赖,就能去触发更改。 接着看实际实现 我们对变量设为响应式对象,会用ref方法,ref方法的实现中调用了toReactive toReactive调用了reactive

reactive调用createReactiveObject,并把mutableHandlers传入了参数

createReactiveObject使用了proxy,把mutableHandlers作为proxy的handler

vue 计算属性未重新计算 / computed 未触发 / computed 原理&源码分析(vue3 计算属性)

然后我们看看handler是怎么做的

可以看到当get时,即获取响应式对象值时,调用了track方法,这里就是在收集依赖了,当我们在computed方法获取响应式对象时,这个computed就作为了target传入去,现在看看track方法做了什么 这里是{target -> key -> dep}的两个map,target就是每一个响应式对象,key就是这个对象上的属性名,dep里就存放了依赖这个属性的响应式对象列表,可以看到下面trackEffects函数里,有一行dep.add(activeEffect) 这里的activeEffect就是当前在运行的响应式对象,就是computed计算属性,被加到dep里了。因此,在computed里用到的其他响应式对象,当computed被执行时,其他响应式对象对应属性里就会维护一个列表,列表里放的是依赖这个属性的响应式对象,依赖收集完成。 之后就是触发了 这里用proxy改了set方法,会去调用trigger函数

看看trigger函数如何实现 trigger函数的target是改了值的响应式对象本身,key是更改的属性名,然后从刚刚说的{target -> key -> dep}两个map里,拿到依赖这个对象这个key的列表deps,这里还能看到如果改的是length,还会有额外操作,感兴趣的可以去看源码,在effect.ts文件。 之后就调用triggerEffects方法,参数其实就是deps,

然后就会去调用triggerEffect(说实话,我还没看到为啥355和360行的代码要这样写),这里如果有scheduler就会去执行,这里的scheduler是构造函数的第二个参数

能找到是在ComputedRefImpl的构造函数赋值的,这里会把dirty改为true,然后会调用triggerRefValue triggerRefValue有调用triggerEffects了,是不是很熟悉?没错是解决假设你的计算属性被其他计算属性所以的,就会继续triggerEffects下去 那实际在哪里改变值呢?还记得刚刚把dirty改为true了吗?computed的实现了,get函数如果dirty为true,就会重新计算 这样,computed就更新了。

看完源码,终于懂了!如果在计算属性里没有明确获取某个响应式对象的某个key,那改了这个key,是不会重新执行computed的,所以就会有开头demo的现象。

回到文档

因此,如果我仍想要有side effects,又不肯换watchers,可以明确获取一下会改变的属性值。但要记住这个知识点,可能相比有side effects就用watchers更复杂吧? 除非代码很多,难得改🐶

有不懂欢迎评论,一起探讨

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

上一篇:vue2移动端使用vue-qrcode-reader实现扫一扫功能(vue 移动端)

下一篇:同步与异步的认识(同步和异步的关系)

  • 跨年发票入账账务处理
  • 初税亩是什么意思
  • 财务软件交多少钱印花税
  • 利润表中的所得税
  • 预提的费用在做所得税的时候如何处理
  • 个税申报的收入是应发工资还是实发工资
  • 股权转让有哪些方式
  • 汽车保险费可以抵扣吗
  • 应发工资包含扣款吗
  • 建安企业无收入怎么结转成本?
  • 超出发票使用范围
  • 营改增之后税务是否可以征收入库?
  • 小规模纳税人第四季度怎么报税
  • 补缴以前年度个税会计处理
  • 营改增的作用
  • 已抵扣发票如何查询开票明细
  • 汇票贴息会计分录
  • 现金短缺属于出纳员负责如何做会计处理
  • 制造费用和劳务成本
  • 外汇扣税是多少钱啊
  • 城市维护建设税属于什么科目
  • 应收款项包括哪些内容,各自有何特点?
  • 政府补助专项资金账务处理
  • 公司借银行款会计分录
  • 企业增值税征收范围包括
  • win10系统如何设置开机启动软件
  • 解决思路怎么写
  • neotrace.exe - neotrace是什么进程 有什么用
  • win10记事本怎么改字体颜色
  • mac怎么删除cineware
  • 集团公司对子公司如何进行资金管理
  • php多任务
  • 分配股利怎么算
  • 工程质保金如何做账
  • 新政府会计制度科目解读
  • 个人所得税的现状分析
  • 基于SadTalker的AI主播,Stable Diffusion也可用
  • php socket_create
  • python打开文本文档中文读不出来
  • 民办非企业单位属于什么类型
  • 无票收入交不交增值税
  • 加计抵减会计分录其他收益
  • 低值易耗品摊销会计处理
  • 合营企业和联营企业都是权益法吗
  • 个人所得税汇算清缴
  • sqlserver2008新建实例
  • mysql日期和时间类型
  • 用友t3采购订单怎么录入
  • 制造费用怎么写
  • 建筑安装行业都需要什么资格证书
  • 异地预缴怎么填写申报表
  • 产房日常维修费用
  • 福利费可以计入销售费用吗
  • 商标使用权入股要交税吗
  • 成本费用占营业收入比重
  • 稳岗补贴如何入账
  • 银行存款利息记账凭证
  • 递延所得税资产和递延所得税负债
  • 会计可以用收据做账吗
  • 一般纳税人的发票抵扣有效期多久
  • sql2005 存储过程 某个字段小于某个值时变颜色
  • mysql删除的数据恢复
  • win8系统如何查看电脑内存
  • ubuntu命令联网
  • win8怎么外接屏幕
  • javascript例题
  • vtune自动安装脚本分享
  • python3m
  • NodeJS配置HTTPS服务实例分享
  • 批处理文件是将需要连续使用的可多次重复使用的
  • html超链接打开本地文件
  • unity 更新
  • js启动
  • unity 移动应用开发
  • android进程间通信机制有哪些
  • 解决js请求服务问题
  • 严格模式的作用
  • 开票系统怎么升级?
  • 广东省电子税务局登录方式
  • 怎么样开通深圳医保
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设