瀏覽代碼

wip: vapor hmr reload

Evan You 1 年之前
父節點
當前提交
54c29aba9a

+ 1 - 1
packages/runtime-core/src/component.ts

@@ -491,7 +491,7 @@ export interface GenericComponentInstance {
   /**
    * @internal vapor only
    */
-  hmrReload?: () => void
+  hmrReload?: (newComp: any) => void
 }
 
 /**

+ 1 - 1
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) {

+ 1 - 1
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[]) {

+ 3 - 1
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<string, any>
   devtoolsRawSetupState?: any
   hmrRerender?: () => void
-  hmrReload?: () => void
+  hmrReload?: (newComp: VaporComponent) => void
   propsOptions?: NormalizedPropsOptions
   emitsOptions?: ObjectEmitsOptions | null
+  isSingleRoot?: boolean
 
   constructor(
     comp: VaporComponent,

+ 26 - 4
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)
 }