上一节我们分析到,vue在diff过程中将对子组件进行更新,调用子组件的prepatch,继而执行updateChildComponent。在updateChildComponent做props更新过程中将触发set发布广播触发watcher的update,继而执行子组件的patch,传入的新旧节点为:上一次渲染vnode、当前渲染vnode
组件节点是没有节点类型的,故isRealElement为false
执行sameVnode,本次的tag分别是ul和div,故返回false
拿到旧节点的根元素ul,父元素main
调用createElm,入参为:当前渲染vnode、[]、id为app的main元素、文本节点
当前的vnode非组件vnode,故createComponent为false
代码向下,data={attr:{id:"child"}}
children="我是flag"
tag="div"
vnode.elm=调用原生dom api创建的div元素
调用createChildren,创建子元素,本次示例只有一个文本元素"我是flag"
调用insert,此时页面将显示出"我是falg"和旧的"1"
回到patch,执行update,更新在父vnode中保存的占位的组件vnode
ancestor=旧的组件vnode
patchable=true。这是因为当前的vnode非组件vnode,其存在真实可挂载的dom节点tag
执行while循环,首先对模块执行销毁工作,这正好对应了在更新过程中添加的元素模块,如id、ref等。代码向下,如果是真实的dom节点,则重新挂载模块(可参考上一节中对cbs.update的分析)
(也就是说,while实际上是先递归的<可能存在组件嵌套的情况>向上将模块销毁,后添加一遍)
代码向下,执行destory,删除旧节点
网友评论