美文网首页前端开发那些事儿
vue源码解读--props(更新)

vue源码解读--props(更新)

作者: 习惯水文的前端苏 | 来源:发表于2021-02-27 16:33 被阅读0次

    目录导航

    本节示例代码如下

    父组件

    子组件

    定位断点

        经过之前章节的介绍,我们知道了。父组件中存在components属性时将会调用extend构建子组件构造器,之后在render过程中将会调用createComponent并在该函数中执行extractPropsFromVNodeData提取父组件通过props传递的数据并保存在组件vnode的componentOptions上,并在update的patch过程中执行子组件的init,在组件的init过程中会对props进行两步处理:将props规范成对象形式;对props进行校验并设置响应式最终架设proxy代理。之后当父组件更新时将会调用patchVnode对子组件进行updateChildren并调用子组件的prepatch继而执行updateChildComponent。因此将代码debugger到该函数

    \bullet change age按钮被点击

            当点击change age按钮,将触发子组件更新,执行updateChildComponent函数,传入prop对象即:{age:12,person:{age:12},school:{name:'xxx第一高级中学',address:"xxx市xxx区"}},将代码定位到props的更新位置

                    \circ toggleObserving用于控制是否对key作响应式处理。由于props已经在父组件的data初始化过程中被Object.defineproperty处理过,且我们本次的触发就是通过修改父组件的props执行过来的,故子组件不需要重复观测

                    \circ props拿到我们传入的props对象

                    \circ _propKeys是我们在initProps过程中缓存的props的key数据,它是被组件接收使用的key集合,因此,对于在组件传入未接收的值vue是不做处理的

                    \circ 对所有的key重新校验一遍以合法,并设置props.key。由于props.key已是响应式的了,故会触发set进行派发更新。由于组件在初次渲染时已经对age进行过访问,因此dep中已经收集到了子组件的render watcher。故将会触发子组件watcher的run进行子组件的update将值正确patch到dom上

    \bullet change person按钮被点击

                    同样的,在子组件初次渲染时访问过person.age故将子组件render watcher收集到了dep中,因此当触发set时一样能够触发子组件的render watcher做update。不一样的是,person是一个引用值,这意味着,父组件和子组件的person指向的是同一个值,因此当父组件中修改person时将能够直接触发子组件的set进行update(这是因为person.age是先访问后修改的过程,在访问时收集了子组件的dep,由于是一个对象类型故会调用obseve将子属性age观测起来,因此在父组件中调用this.person将收集依赖,this.person.age将触发age的notify)。其效果和子组件中修改是一样的。那么这与vue的单项数据流冲突吗,是否会报warn呢?不会的!因为在init props中传递的setter是这样的

            vue只对key设置了set,即{age:12},我们改的是age,而非{age:12},故不会触发warn警告

    \bullet change school按钮被点击

            综合一、二两种,我们可以得出结论,对对象引用的修改会触发新一轮的父组件patch过程,和change age的流程一样。这是因为在决定是否notify之前,会先进行值判断

    (两次引用必然不相等)

    相关文章

      网友评论

        本文标题:vue源码解读--props(更新)

        本文链接:https://www.haomeiwen.com/subject/xzdpfltx.html