HcySunYang / vue-design

📖 master分支:《渲染器》
http://hcysun.me/vue-design/zh/
6k stars 918 forks source link

当childFlags为NO_CHILDREN时patch过程的问题 #260

Open x-shadow-x opened 5 years ago

x-shadow-x commented 5 years ago

文中提到patch的九种情况,其中提到在旧的children为单个子节点而新的children为没有子节点的时候,仅仅container.removeChild(prevChildren.el)会遇到一个片段的问题,需要另外处理。这里对两种情况有个疑惑: 1、新children为没有子节点,旧children是单个子节点 2、新children为没有子节点,旧children是多个子节点 文章中的处理方式分别如下:

case ChildrenFlags.NO_CHILDREN:
          container.removeChild(prevChildren.el)
          break
case ChildrenFlags.NO_CHILDREN:
          for (let i = 0; i < prevChildren.length; i++) {
            container.removeChild(prevChildren[i].el)
          }
          break

对于以上两种情况对应的移除子节点的方式,初看觉得很自然,根据旧VNode的el找回之前添加的元素并将其删除,不过细想,何不直接使用container.innerHTML = ''。 理由是:以第二次render为例,此时新的children为无子节点,container下目前具有的子节点都是第一次render通过mount渲染到容器的,在使用vue2的时候,事先在根容器<div id="app"></div>里面写内容最后是会被替换掉的,那就应该不会存在容器里面事先存在不是由mount渲染进去的子元素(即当前容器里面存在的所有的子元素都是上一次mount进来的),那我就直接删掉容器里面所有的内容,这样前面提到的片段渲染多个子元素到容器的问题就自然解决了,不过我不是很清楚这样简单粗暴的方式是否有哪些边界情况没有考虑到,求解答,谢谢