Преглед изворни кода

fix: ensure outer bindings on nested HOC are properly re-applied on inner root element change

Evan You пре 8 година
родитељ
комит
a744497534
2 измењених фајлова са 37 додато и 5 уклоњено
  1. 9 5
      src/core/vdom/patch.js
  2. 28 0
      test/unit/modules/vdom/patch/edge-cases.spec.js

+ 9 - 5
src/core/vdom/patch.js

@@ -660,14 +660,18 @@ export function createPatchFunction (backend) {
           // component root element replaced.
           // update parent placeholder node element, recursively
           let ancestor = vnode.parent
+          const patchable = isPatchable(vnode)
           while (ancestor) {
+            for (let i = 0; i < cbs.destroy.length; ++i) {
+              cbs.destroy[i](ancestor)
+            }
             ancestor.elm = vnode.elm
-            ancestor = ancestor.parent
-          }
-          if (isPatchable(vnode)) {
-            for (let i = 0; i < cbs.create.length; ++i) {
-              cbs.create[i](emptyNode, vnode.parent)
+            if (patchable) {
+              for (let i = 0; i < cbs.create.length; ++i) {
+                cbs.create[i](emptyNode, ancestor)
+              }
             }
+            ancestor = ancestor.parent
           }
         }
 

+ 28 - 0
test/unit/modules/vdom/patch/edge-cases.spec.js

@@ -161,4 +161,32 @@ describe('vdom patch: edge cases', () => {
       expect(vm.$el.children[0].type).toBe('password')
     }).then(done)
   })
+
+  it('should properly patch nested HOC when root element is replaced', done => {
+    const vm = new Vue({
+      template: `<foo class="hello" ref="foo" />`,
+      components: {
+        foo: {
+          template: `<bar ref="bar" />`,
+          components: {
+            bar: {
+              template: `<div v-if="ok"></div><span v-else></span>`,
+              data () {
+                return { ok: true }
+              }
+            }
+          }
+        }
+      }
+    }).$mount()
+
+    expect(vm.$refs.foo.$refs.bar.$el.tagName).toBe('DIV')
+    expect(vm.$refs.foo.$refs.bar.$el.className).toBe(`hello`)
+
+    vm.$refs.foo.$refs.bar.ok = false
+    waitForUpdate(() => {
+      expect(vm.$refs.foo.$refs.bar.$el.tagName).toBe('SPAN')
+      expect(vm.$refs.foo.$refs.bar.$el.className).toBe(`hello`)
+    }).then(done)
+  })
 })