Browse Source

fix(fragment): perform direct remove when removing fragments

This avoids trying to grab .el from hoisted child nodes (which can
be created by another instance), and also skips transition check
since fragment children cannot have transitions.
Evan You 6 years ago
parent
commit
2fdb499bd9
1 changed files with 16 additions and 10 deletions
  1. 16 10
      packages/runtime-core/src/renderer.ts

+ 16 - 10
packages/runtime-core/src/renderer.ts

@@ -1573,10 +1573,14 @@ export function createRenderer<
   }
   }
 
 
   function remove(vnode: HostVNode) {
   function remove(vnode: HostVNode) {
-    const { type, el, anchor, children, transition } = vnode
+    const { type, el, anchor, transition } = vnode
+    if (type === Fragment) {
+      removeFragment(el!, anchor!)
+      return
+    }
+
     const performRemove = () => {
     const performRemove = () => {
       hostRemove(el!)
       hostRemove(el!)
-      if (anchor != null) hostRemove(anchor)
       if (
       if (
         transition != null &&
         transition != null &&
         !transition.persisted &&
         !transition.persisted &&
@@ -1585,11 +1589,7 @@ export function createRenderer<
         transition.afterLeave()
         transition.afterLeave()
       }
       }
     }
     }
-    if (type === Fragment) {
-      performRemove()
-      removeChildren(children as HostVNode[])
-      return
-    }
+
     if (
     if (
       vnode.shapeFlag & ShapeFlags.ELEMENT &&
       vnode.shapeFlag & ShapeFlags.ELEMENT &&
       transition != null &&
       transition != null &&
@@ -1607,10 +1607,16 @@ export function createRenderer<
     }
     }
   }
   }
 
 
-  function removeChildren(children: HostVNode[]) {
-    for (let i = 0; i < children.length; i++) {
-      remove(children[i])
+  function removeFragment(cur: HostNode, end: HostNode) {
+    // For fragments, directly remove all contained DOM nodes.
+    // (fragment child nodes cannot have transition)
+    let next
+    while (cur !== end) {
+      next = hostNextSibling(cur)!
+      hostRemove(cur)
+      cur = next
     }
     }
+    hostRemove(end)
   }
   }
 
 
   function unmountComponent(
   function unmountComponent(