fix HOC root node replace updates

This commit is contained in:
Evan You 2016-07-07 15:30:42 -04:00
parent e0c77dd48d
commit dffeb1d1c2
3 changed files with 53 additions and 9 deletions

View File

@ -85,15 +85,9 @@ export function lifecycleMixin (Vue: Class<Component>) {
if (vm.$el) {
vm.$el.__vue__ = vm
}
// update parent vnode element after patch
const parentNode = vm.$vnode
if (parentNode) {
parentNode.elm = vm.$el
// update parent $el if the parent is HOC
// this is necessary because child is updated after parent
if (vm.$parent && parentNode === vm.$parent._vnode) {
vm.$parent.$el = vm.$el
}
// if parent is an HOC, update its $el as well
if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) {
vm.$parent.$el = vm.$el
}
if (vm._isMounted) {
callHook(vm, 'updated')

View File

@ -83,6 +83,7 @@ export function createPatchFunction (backend) {
// component also has set the placeholder vnode's elm.
// in that case we can just return the element and be done.
if (isDef(i = vnode.child)) {
vnode.elm = vnode.child.$el
invokeCreateHooks(vnode, insertedVnodeQueue)
setScope(vnode)
return vnode.elm
@ -415,6 +416,15 @@ export function createPatchFunction (backend) {
createElm(vnode, insertedVnodeQueue)
// component root element replaced.
// update parent placeholder node element.
if (vnode.parent) {
vnode.parent.elm = vnode.elm
for (let i = 0; i < cbs.create.length; ++i) {
cbs.create[i](emptyNode, vnode.parent)
}
}
if (parent !== null) {
nodeOps.insertBefore(parent, vnode.elm, nodeOps.nextSibling(elm))
removeVnodes(parent, [oldVnode], 0, 0)

View File

@ -236,4 +236,44 @@ describe('Component', () => {
})
}).not.toThrow()
})
it('properly update replaced higher-order component root node', done => {
const vm = new Vue({
data: {
color: 'red'
},
template: '<test id="foo" :class="color"></test>',
components: {
test: {
data () {
return { tag: 'div' }
},
render (h) {
return h(this.tag, { class: 'test' }, 'hi')
}
}
}
}).$mount()
expect(vm.$el.tagName).toBe('DIV')
expect(vm.$el.id).toBe('foo')
expect(vm.$el.className).toBe('test red')
vm.color = 'green'
waitForUpdate(() => {
expect(vm.$el.tagName).toBe('DIV')
expect(vm.$el.id).toBe('foo')
expect(vm.$el.className).toBe('test green')
vm.$children[0].tag = 'p'
}).then(() => {
expect(vm.$el.tagName).toBe('P')
expect(vm.$el.id).toBe('foo')
expect(vm.$el.className).toBe('test green')
vm.color = 'red'
}).then(() => {
expect(vm.$el.tagName).toBe('P')
expect(vm.$el.id).toBe('foo')
expect(vm.$el.className).toBe('test red')
}).then(done)
})
})