mirror of https://github.com/vuejs/vue.git
fix HOC root node replace updates
This commit is contained in:
parent
e0c77dd48d
commit
dffeb1d1c2
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue