浏览代码

fix(teleport): always inherit root DOM nodes on patch (#1836)

fix #1813
zhangzhonghe 5 年之前
父节点
当前提交
517c2b8bdb
共有 2 个文件被更改,包括 43 次插入1 次删除
  1. 4 1
      packages/runtime-core/src/components/Teleport.ts
  2. 39 0
      packages/vue/__tests__/index.spec.ts

+ 4 - 1
packages/runtime-core/src/components/Teleport.ts

@@ -139,7 +139,10 @@ export const TeleportImpl = {
           parentSuspense,
           isSVG
         )
-        if (n2.patchFlag > 0 && n2.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
+        // even in block tree mode we need to make sure all root-level nodes
+        // in the teleport inherit previous DOM references so that they can
+        // be moved in future patches.
+        if (n2.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
           const oldChildren = n1.children as VNode[]
           const children = n2.children as VNode[]
           for (let i = 0; i < children.length; i++) {

+ 39 - 0
packages/vue/__tests__/index.spec.ts

@@ -208,4 +208,43 @@ describe('compiler + runtime integration', () => {
     ).toHaveBeenWarned()
     document.querySelector = origin
   })
+
+  // #1813
+  it('should not report an error when "0" as patchFlag value', async () => {
+    const container = document.createElement('div')
+    const target = document.createElement('div')
+    const count = ref(0)
+    const origin = document.querySelector
+    document.querySelector = jest.fn().mockReturnValue(target)
+
+    const App = {
+      template: `
+      <teleport v-if="count < 2" to="#target">
+        <div>
+          <div>{{ count }}</div>
+        </div>
+      </teleport>
+      `,
+      data() {
+        return {
+          count
+        }
+      }
+    }
+    createApp(App).mount(container)
+    expect(container.innerHTML).toBe(`<!--teleport start--><!--teleport end-->`)
+    expect(target.innerHTML).toBe(`<div><div>0</div></div>`)
+
+    count.value++
+    await nextTick()
+    expect(container.innerHTML).toBe(`<!--teleport start--><!--teleport end-->`)
+    expect(target.innerHTML).toBe(`<div><div>1</div></div>`)
+
+    count.value++
+    await nextTick()
+    expect(container.innerHTML).toBe(`<!--v-if-->`)
+    expect(target.innerHTML).toBe(``)
+
+    document.querySelector = origin
+  })
 })