- 如果被挂载过,也就是isMounted为true,触发effect的时候就会走组件更新的逻辑
- diff算法就是比较两颗树的差异
第一步
我们先拿到老的的tree
然后把当前实例上的proxy数据传入render里,再调render方法就拿到了新的tree
第二步
调用patch方法,patch方法既有初始化,又有更新的功能
传了第一个参数,就是更新,否则就是初始化
这时候会走元素更新
判断是否值得比较
当走到patch方法的时候,我们就来看看值不值的去比较
- 如果n1和n2不是相同的节点,把以前的删掉,换成n2,判断是不是相同,通过type和key
- 获取下一个节点,最后插入下一个节点的前面
第三步
这个时候我们来比较元素
如果元素是相同节点
- 先复用老的dom节点
- 然后更新props
patchProps方法
- 如果新属性和老属性不相等
- 循环新属性对象里的属性,如果和老的不一样,就去更新
- 再去循环老的,如果老的有,新的没有,那就赋值个null
第四步
更新children
patchChildren方法
可能的情况:
- 老的有儿子,新的没儿子
- 新的有儿子,老的没儿子
- 新老都有儿子
- 新老都是文本
- 取出老的shapeFlag和新的shapeFlag
- 先判断新的shapeFlag是否是文本,如果是文本,再去判断老的是数组,也就是否包含组件,如果包含组件则会调用组件的销毁方法
- 然后判断c1和c2是否相同,如果不相同,直接把新的文本插入到容器中
- 如果现在是元素,之前是文本或者数组,老的是文本其实也会被包装成数组,所以到这里也就是两个数组的比对,也就是核心的diff算法
- 否则就是没有孩子,直接删除掉孩子
- 如果上一次是文本,就直接清空,如果这次有儿子,直接挂载上去
对这个方法来个总结
- 现在是文本之前是数组,销毁之前的所有儿子
- 两个人都是文本,直接替换
- 两个人都是数组,进行diff
- 现在是数组,之前是文本,清空之前文本,挂载现在的所有儿子
下一步,我们就开始详细去分析diff算法
如果您觉得有所收获,麻烦动动小手点个攒,谢谢啦~ 预知后事如何,且听下回分解~