Просмотр исходного кода

fix #5321 don't throw error when node gets relocated (#5322)

* don't throw error when node gets relocated

* perf: Simplify if check in vdom/patch
Razvan Stoenescu 9 лет назад
Родитель
Сommit
255b627f39
2 измененных файлов с 45 добавлено и 1 удалено
  1. 3 1
      src/core/vdom/patch.js
  2. 42 0
      test/unit/features/component/component.spec.js

+ 3 - 1
src/core/vdom/patch.js

@@ -234,7 +234,9 @@ export function createPatchFunction (backend) {
   function insert (parent, elm, ref) {
     if (isDef(parent)) {
       if (isDef(ref)) {
-        nodeOps.insertBefore(parent, elm, ref)
+        if (ref.parentNode === parent) {
+          nodeOps.insertBefore(parent, elm, ref)
+        }
       } else {
         nodeOps.appendChild(parent, elm)
       }

+ 42 - 0
test/unit/features/component/component.spec.js

@@ -366,4 +366,46 @@ describe('Component', () => {
       Vue.config.errorHandler = null
     }).then(done)
   })
+
+  it('relocates node without error', done => {
+    const el = document.createElement('div')
+    document.body.appendChild(el)
+    const target = document.createElement('div')
+    document.body.appendChild(target)
+
+    const Test = {
+      render (h) {
+        return h('div', { class: 'test' }, this.$slots.default)
+      },
+      mounted () {
+        target.appendChild(this.$el)
+      },
+      beforeDestroy () {
+        const parent = this.$el.parentNode
+        if (parent) {
+          parent.removeChild(this.$el)
+        }
+      }
+    }
+    const vm = new Vue({
+      data () {
+        return {
+          view: true
+        }
+      },
+      template: `<div><test v-if="view">Test</test></div>`,
+      components: {
+        test: Test
+      }
+    }).$mount(el)
+
+    expect(el.outerHTML).toBe('<div></div>')
+    expect(target.outerHTML).toBe('<div><div class="test">Test</div></div>')
+    vm.view = false
+    waitForUpdate(() => {
+      expect(el.outerHTML).toBe('<div></div>')
+      expect(target.outerHTML).toBe('<div></div>')
+      vm.$destroy()
+    }).then(done)
+  })
 })