diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index 8a8129ffd..58b1bd642 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -491,7 +491,7 @@ export interface GenericComponentInstance { /** * @internal vapor only */ - hmrReload?: () => void + hmrReload?: (newComp: any) => void } /** diff --git a/packages/runtime-core/src/componentCurrentInstance.ts b/packages/runtime-core/src/componentCurrentInstance.ts index e0322e0c9..c091b9c69 100644 --- a/packages/runtime-core/src/componentCurrentInstance.ts +++ b/packages/runtime-core/src/componentCurrentInstance.ts @@ -96,7 +96,7 @@ export const unsetCurrentInstance = (): void => { */ export const simpleSetCurrentInstance = ( i: GenericComponentInstance | null, - unset?: GenericComponentInstance, + unset?: GenericComponentInstance | null, ): void => { currentInstance = i if (unset) { diff --git a/packages/runtime-core/src/hmr.ts b/packages/runtime-core/src/hmr.ts index b2c52ab3e..42f671e81 100644 --- a/packages/runtime-core/src/hmr.ts +++ b/packages/runtime-core/src/hmr.ts @@ -119,7 +119,7 @@ function reload(id: string, newComp: HMRComponent): void { if (newComp.vapor) { for (const instance of instances) { - instance.hmrReload!() + instance.hmrReload!(newComp) } } else { for (const instance of instances as ComponentInternalInstance[]) { diff --git a/packages/runtime-vapor/src/component.ts b/packages/runtime-vapor/src/component.ts index 74c2fa2d3..7334bbecf 100644 --- a/packages/runtime-vapor/src/component.ts +++ b/packages/runtime-vapor/src/component.ts @@ -150,6 +150,7 @@ export function createComponent( // HMR if (component.__hmrId) { registerHMR(instance) + instance.isSingleRoot = isSingleRoot instance.hmrRerender = hmrRerender.bind(null, instance) instance.hmrReload = hmrReload.bind(null, instance) } @@ -260,9 +261,10 @@ export class VaporComponentInstance implements GenericComponentInstance { setupState?: Record devtoolsRawSetupState?: any hmrRerender?: () => void - hmrReload?: () => void + hmrReload?: (newComp: VaporComponent) => void propsOptions?: NormalizedPropsOptions emitsOptions?: ObjectEmitsOptions | null + isSingleRoot?: boolean constructor( comp: VaporComponent, diff --git a/packages/runtime-vapor/src/hmr.ts b/packages/runtime-vapor/src/hmr.ts index 5e9616b39..f01b337bd 100644 --- a/packages/runtime-vapor/src/hmr.ts +++ b/packages/runtime-vapor/src/hmr.ts @@ -5,7 +5,14 @@ import { simpleSetCurrentInstance, } from '@vue/runtime-core' import { normalizeBlock } from './block' -import { type VaporComponentInstance, devRender } from './component' +import { + type VaporComponent, + type VaporComponentInstance, + createComponent, + devRender, + mountComponent, + unmountComponent, +} from './component' import { insert, remove } from './dom/node' export function hmrRerender(instance: VaporComponentInstance): void { @@ -22,7 +29,22 @@ export function hmrRerender(instance: VaporComponentInstance): void { insert(instance.block, parent, anchor) } -export function hmrReload(instance: VaporComponentInstance): void { - // in parent block, find the corresponding block of this instance - // create new instance, replace +export function hmrReload( + instance: VaporComponentInstance, + newComp: VaporComponent, +): void { + const normalized = normalizeBlock(instance.block) + const parent = normalized[0].parentNode! + const anchor = normalized[normalized.length - 1].nextSibling + unmountComponent(instance, parent) + const prev = currentInstance + simpleSetCurrentInstance(instance.parent) + const newInstance = createComponent( + newComp, + instance.rawProps, + instance.rawSlots, + instance.isSingleRoot, + ) + simpleSetCurrentInstance(prev, instance.parent) + mountComponent(newInstance, parent, anchor) }