添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
  • 20+个很棒的 Python 脚本的集合(迷你项目) (184125)
  • 解决报错:org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 : [no body] (13822)
  • STM32单片机之温湿度检测系统(DTH11、OLED、LCD1602) (9686)
  • 安装Photoshop时出现The installation cannot continue as the installer file may be damaged. Download the in (9112)
  • 误差分析计算公式及其 matlab 代码实现(mse、mape、rmse等) (8114)
  • 【elementUI】关于el-input限制输入整数、数字范围以及在form表单验证中限制输入正整数 (7677)
  • 手把手教你配置linux下C++开发工具——vim+ycm(YouCompleteMe),支持基于语义的自动补全和第三方库补全(史上最简单、史上最透彻、史上最全的终极解决方案) (6407)
  • 【Yolo3】一文掌握图像标注、训练、识别(Keras+TensorFlow-gpu) (4993)
  • 基于STM32L431设计的云端绿化管理系统(ESP8266+阿里云物联网平台) (4866)
  • Android Studio 模拟器一段时间后Toast不显示,System UI isn‘t responding等问题简单解决方法 (4691)
  • Vue中 引入使用 babel-polyfill 兼容低版本浏览器 (0)
  • 1000亿数据、30W级qps如何架构?来一个天花板案例 (0)
  • STM32开发(16)----CubeMX配置DMA (0)
  • Hadoop综合案例 - 聊天软件数据 (0)
  • 基于JWT实现用户身份认证 (0)
  • 【企业云端全栈开发实践-2】Spring Boot Controller (0)
  • 使用手工特征提升模型性能 (0)
  • 《MySql学习》 Select 查询语句慢的非性能原因 (0)
  • 客户端攻击(溯源攻击,获取客户端信息) (0)
  • 20+个很棒的 Python 脚本的集合(迷你项目)
  • 又发现一个ChatGPT国内镜像站,无次数限制也无广告
  • 解决报错:org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 : [no body]
  • Proxy error: Could not proxy request
  • 解决 eslint 的 Parsing error: Unexpected token 错误
  • 五、肺癌检测-数据集训练 training.py model.py
  • STM32单片机之温湿度检测系统(DTH11、OLED、LCD1602)
  • 安装Photoshop时出现The installation cannot continue as the installer file may be damaged. Download the in
  • echarts——实现3D地图+3D柱状图 效果——粗糙代码记录——技能提升
  • 误差分析计算公式及其 matlab 代码实现(mse、mape、rmse等)
  • 点击可打开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

    然后我们看看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://blog.csdn.net/ZhaoBuDaoFangXia/article/details/128099075