mirror of https://github.com/vuejs/core.git
fix(hmr): prevent updating unmounting component during HMR rerender (#13775)
close #13771 close #13772
This commit is contained in:
parent
1498821ed9
commit
6e5143d963
|
@ -894,4 +894,47 @@ describe('hot module replacement', () => {
|
||||||
await timeout()
|
await timeout()
|
||||||
expect(serializeInner(root)).toBe('<div>bar</div>')
|
expect(serializeInner(root)).toBe('<div>bar</div>')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('rerender for nested component', () => {
|
||||||
|
const id = 'child-nested-rerender'
|
||||||
|
const Foo: ComponentOptions = {
|
||||||
|
__hmrId: id,
|
||||||
|
render() {
|
||||||
|
return this.$slots.default()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
createRecord(id, Foo)
|
||||||
|
|
||||||
|
const parentId = 'parent-nested-rerender'
|
||||||
|
const Parent: ComponentOptions = {
|
||||||
|
__hmrId: parentId,
|
||||||
|
render() {
|
||||||
|
return h(Foo, null, {
|
||||||
|
default: () => this.$slots.default(),
|
||||||
|
_: 3 /* FORWARDED */,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const appId = 'app-nested-rerender'
|
||||||
|
const App: ComponentOptions = {
|
||||||
|
__hmrId: appId,
|
||||||
|
render: () =>
|
||||||
|
h(Parent, null, {
|
||||||
|
default: () => [
|
||||||
|
h(Foo, null, {
|
||||||
|
default: () => ['foo'],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
createRecord(parentId, App)
|
||||||
|
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
render(h(App), root)
|
||||||
|
expect(serializeInner(root)).toBe('foo')
|
||||||
|
|
||||||
|
rerender(id, () => 'bar')
|
||||||
|
expect(serializeInner(root)).toBe('bar')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
type InternalRenderFunction,
|
type InternalRenderFunction,
|
||||||
isClassComponent,
|
isClassComponent,
|
||||||
} from './component'
|
} from './component'
|
||||||
import { queueJob, queuePostFlushCb } from './scheduler'
|
import { SchedulerJobFlags, queueJob, queuePostFlushCb } from './scheduler'
|
||||||
import { extend, getGlobalThis } from '@vue/shared'
|
import { extend, getGlobalThis } from '@vue/shared'
|
||||||
|
|
||||||
type HMRComponent = ComponentOptions | ClassComponent
|
type HMRComponent = ComponentOptions | ClassComponent
|
||||||
|
@ -96,7 +96,10 @@ function rerender(id: string, newRender?: Function): void {
|
||||||
instance.renderCache = []
|
instance.renderCache = []
|
||||||
// this flag forces child components with slot content to update
|
// this flag forces child components with slot content to update
|
||||||
isHmrUpdating = true
|
isHmrUpdating = true
|
||||||
instance.update()
|
// #13771 don't update if the job is already disposed
|
||||||
|
if (!(instance.job.flags! & SchedulerJobFlags.DISPOSED)) {
|
||||||
|
instance.update()
|
||||||
|
}
|
||||||
isHmrUpdating = false
|
isHmrUpdating = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue