mirror of https://github.com/vuejs/core.git
fix(hmr): prevent update unmounting component during HMR reload (#13815)
close vitejs/vite-plugin-vue#599
This commit is contained in:
parent
35da3c6dcb
commit
ef20b86b36
|
@ -937,4 +937,55 @@ describe('hot module replacement', () => {
|
||||||
rerender(id, () => 'bar')
|
rerender(id, () => 'bar')
|
||||||
expect(serializeInner(root)).toBe('bar')
|
expect(serializeInner(root)).toBe('bar')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// https://github.com/vitejs/vite-plugin-vue/issues/599
|
||||||
|
// Both Outer and Inner are reloaded when './server.js' changes
|
||||||
|
test('reload nested components from single update', async () => {
|
||||||
|
const innerId = 'nested-reload-inner'
|
||||||
|
const outerId = 'nested-reload-outer'
|
||||||
|
|
||||||
|
let Inner = {
|
||||||
|
__hmrId: innerId,
|
||||||
|
render() {
|
||||||
|
return h('div', 'foo')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
let Outer = {
|
||||||
|
__hmrId: outerId,
|
||||||
|
render() {
|
||||||
|
return h(Inner)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
createRecord(innerId, Inner)
|
||||||
|
createRecord(outerId, Outer)
|
||||||
|
|
||||||
|
const App = {
|
||||||
|
render: () => h(Outer),
|
||||||
|
}
|
||||||
|
|
||||||
|
const root = nodeOps.createElement('div')
|
||||||
|
render(h(App), root)
|
||||||
|
expect(serializeInner(root)).toBe('<div>foo</div>')
|
||||||
|
|
||||||
|
Inner = {
|
||||||
|
__hmrId: innerId,
|
||||||
|
render() {
|
||||||
|
return h('div', 'bar')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
Outer = {
|
||||||
|
__hmrId: outerId,
|
||||||
|
render() {
|
||||||
|
return h(Inner)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// trigger reload for both Outer and Inner
|
||||||
|
reload(outerId, Outer)
|
||||||
|
reload(innerId, Inner)
|
||||||
|
await nextTick()
|
||||||
|
|
||||||
|
expect(serializeInner(root)).toBe('<div>bar</div>')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -147,11 +147,15 @@ function reload(id: string, newComp: HMRComponent): void {
|
||||||
// components to be unmounted and re-mounted. Queue the update so that we
|
// components to be unmounted and re-mounted. Queue the update so that we
|
||||||
// don't end up forcing the same parent to re-render multiple times.
|
// don't end up forcing the same parent to re-render multiple times.
|
||||||
queueJob(() => {
|
queueJob(() => {
|
||||||
isHmrUpdating = true
|
// vite-plugin-vue/issues/599
|
||||||
instance.parent!.update()
|
// don't update if the job is already disposed
|
||||||
isHmrUpdating = false
|
if (!(instance.job.flags! & SchedulerJobFlags.DISPOSED)) {
|
||||||
// #6930, #11248 avoid infinite recursion
|
isHmrUpdating = true
|
||||||
dirtyInstances.delete(instance)
|
instance.parent!.update()
|
||||||
|
isHmrUpdating = false
|
||||||
|
// #6930, #11248 avoid infinite recursion
|
||||||
|
dirtyInstances.delete(instance)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
} else if (instance.appContext.reload) {
|
} else if (instance.appContext.reload) {
|
||||||
// root instance mounted via createApp() has a reload method
|
// root instance mounted via createApp() has a reload method
|
||||||
|
|
Loading…
Reference in New Issue