位置: 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 移动端)

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

  • 银行委托贷款上征信吗
  • 递延所得税负债转回怎么理解
  • 仓库盘亏怎么处理
  • 抵扣进项税怎么做凭证
  • 餐饮服务需要缴纳增值税吗
  • 季末计提所得税可以根据本年利润计算吗?
  • 工会费个税税前扣除标准
  • 存根联给了客户怎么办
  • 存货核算与销售核算直接联系的是
  • 公司试驾车购置税怎么交
  • 加油费充值卡发票可以报销吗
  • 小规模纳税人可以收13%的专票吗?
  • 药企常见税务风险及措施
  • 公司发票限额按什么计算
  • 企业重组 资产重组
  • 进项税额转出后再转入怎么做账
  • 客户少付货款怎么做账
  • 应收款收不回账务处理
  • 机械租赁的发票
  • 跨月可以开票吗
  • 企业已确认销售收入的售出商品发生销售折让,且不属于
  • 计提个税怎么做
  • 进项发票如何抵扣销项发票
  • 广告公司文化事业费怎么交
  • 不得抵扣的进项税额计入哪里
  • PHP Warning:PHP Startup: in Unknown on line 0解决办法
  • 预收和应收怎么转换
  • real system
  • win11怎么清理内存
  • linux添加系统用户命令
  • 企业现金流量表怎么分析
  • echarts css
  • php开发过程遇到的难题
  • php读取excel内容
  • 当月进项税额转出当月申报吗
  • php注册功能的实现
  • 企业将设备出租应当作为固定资产吗
  • 生产车间工资计提
  • 财务费用的核算属于什么业务
  • php curl 封装
  • 通讯费补贴会计怎么做账
  • 年检车辆检测费
  • 利润分配财务管理
  • 出纳收到现金会计分录
  • 如何用wordpress
  • 织梦专题页模板
  • 如何查询发票领购日期
  • 销货清单是否必须备案
  • 小规模纳税人减免增值税会计处理
  • 代销商品税率是多少
  • 公司收到银行发放贷款会计分录
  • 投资性房地产成本法账务处理
  • 发工资的是会计还是出纳
  • 所得税为负数会计分录
  • 回收材料的好处和问题
  • 车辆购置税具有价外征收转嫁税负的特点吗
  • 小规模纳税人残保金减免政策
  • sql中cursor是什么意思
  • Win10 Mobile 10563预览版微软官方模拟器下载
  • 苹果电脑快捷键截图怎么截
  • sxs.exe病毒
  • Win10中SmartScreen无法设置需要系统管理员身份该怎么办?
  • xp开始菜单栏怎么还原
  • Mac借助其他电脑做系统
  • macbook的dock栏
  • linux系统怎么访问网页
  • windows7旗舰版桌面壁纸怎么更换
  • echarts怎么样
  • android adbd
  • shell echo-e
  • vue.js作用
  • node的全局变量有哪些
  • 用js设置颜色
  • javascript获取html元素的方法
  • Zero Clipboard实现浏览器复制到剪贴板的方法(多个复制按钮)
  • python 元类的作用
  • 江苏省国家税务局
  • 胡世军简历年龄多大
  • 教育培训行业的发展前景
  • 密云到顺义区医院公交路线
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设