mirror of https://github.com/vuejs/core.git
wip: prepare hmr reload
This commit is contained in:
parent
6f449346c9
commit
bb0787b8d4
|
@ -488,6 +488,10 @@ export interface GenericComponentInstance {
|
|||
* @internal vapor only
|
||||
*/
|
||||
hmrRerender?: () => void
|
||||
/**
|
||||
* @internal vapor only
|
||||
*/
|
||||
hmrReload?: () => void
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -96,8 +96,7 @@ function rerender(id: string, newRender?: Function): void {
|
|||
// this flag forces child components with slot content to update
|
||||
isHmrUpdating = true
|
||||
if (instance.vapor) {
|
||||
// @ts-expect-error TODO
|
||||
instance.hmrRerender()
|
||||
instance.hmrRerender!()
|
||||
} else {
|
||||
const i = instance as ComponentInternalInstance
|
||||
i.renderCache = []
|
||||
|
@ -119,7 +118,9 @@ function reload(id: string, newComp: HMRComponent): void {
|
|||
const instances = [...record.instances]
|
||||
|
||||
if (newComp.vapor) {
|
||||
// TODO
|
||||
for (const instance of instances) {
|
||||
instance.hmrReload!()
|
||||
}
|
||||
} else {
|
||||
for (const instance of instances as ComponentInternalInstance[]) {
|
||||
const oldComp = normalizeClassComponent(instance.type as HMRComponent)
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
} from '@vue/runtime-dom'
|
||||
import { type Block, isBlock } from './block'
|
||||
import { pauseTracking, proxyRefs, resetTracking } from '@vue/reactivity'
|
||||
import { EMPTY_OBJ, isFunction, isString } from '@vue/shared'
|
||||
import { EMPTY_OBJ, invokeArrayFns, isFunction, isString } from '@vue/shared'
|
||||
import {
|
||||
type RawProps,
|
||||
getPropsProxyHandlers,
|
||||
|
@ -40,8 +40,8 @@ import {
|
|||
dynamicSlotsProxyHandlers,
|
||||
getSlot,
|
||||
} from './componentSlots'
|
||||
import { insert } from './dom/node'
|
||||
import { hmrRerender } from './hmr'
|
||||
import { insert, remove } from './dom/node'
|
||||
import { hmrReload, hmrRerender } from './hmr'
|
||||
|
||||
export { currentInstance } from '@vue/runtime-dom'
|
||||
|
||||
|
@ -148,6 +148,7 @@ export function createComponent(
|
|||
// HMR
|
||||
registerHMR(instance)
|
||||
instance.hmrRerender = hmrRerender.bind(null, instance)
|
||||
instance.hmrReload = hmrReload.bind(null, instance)
|
||||
}
|
||||
} else {
|
||||
// in prod result can only be block
|
||||
|
@ -202,6 +203,7 @@ export class VaporComponentInstance implements GenericComponentInstance {
|
|||
uid: number
|
||||
type: VaporComponent
|
||||
parent: GenericComponentInstance | null
|
||||
children: VaporComponentInstance[] // TODO handle vdom children
|
||||
appContext: GenericAppContext
|
||||
|
||||
block: Block
|
||||
|
@ -254,6 +256,7 @@ export class VaporComponentInstance implements GenericComponentInstance {
|
|||
setupState?: Record<string, any>
|
||||
devtoolsRawSetupState?: any
|
||||
hmrRerender?: () => void
|
||||
hmrReload?: () => void
|
||||
propsOptions?: NormalizedPropsOptions
|
||||
emitsOptions?: ObjectEmitsOptions | null
|
||||
|
||||
|
@ -266,19 +269,26 @@ export class VaporComponentInstance implements GenericComponentInstance {
|
|||
this.uid = nextUid()
|
||||
this.type = comp
|
||||
this.parent = currentInstance // TODO proper parent source when inside vdom instance
|
||||
this.appContext = currentInstance
|
||||
? currentInstance.appContext
|
||||
: emptyContext
|
||||
this.children = []
|
||||
|
||||
if (currentInstance) {
|
||||
if (isVaporComponent(currentInstance)) {
|
||||
currentInstance.children.push(this)
|
||||
}
|
||||
this.appContext = currentInstance.appContext
|
||||
this.provides = currentInstance.provides
|
||||
this.ids = currentInstance.ids
|
||||
} else {
|
||||
this.appContext = emptyContext
|
||||
this.provides = Object.create(this.appContext.provides)
|
||||
this.ids = ['', 0, 0]
|
||||
}
|
||||
|
||||
this.block = null! // to be set
|
||||
this.scope = new EffectScope(true)
|
||||
|
||||
this.emit = emit.bind(null, this)
|
||||
this.provides = currentInstance
|
||||
? currentInstance.provides
|
||||
: Object.create(this.appContext.provides)
|
||||
this.refs = EMPTY_OBJ
|
||||
this.ids = currentInstance ? currentInstance.ids : ['', 0, 0]
|
||||
this.emitted = this.exposed = this.propsDefaults = this.suspense = null
|
||||
this.isMounted =
|
||||
this.isUnmounted =
|
||||
|
@ -381,3 +391,35 @@ export function createComponentWithFallback(
|
|||
|
||||
return el
|
||||
}
|
||||
|
||||
export function mountComponent(
|
||||
instance: VaporComponentInstance,
|
||||
parent: ParentNode,
|
||||
anchor: Node | null | 0,
|
||||
): void {
|
||||
if (!instance.isMounted) {
|
||||
if (instance.bm) invokeArrayFns(instance.bm)
|
||||
insert(instance.block, parent, anchor)
|
||||
// queuePostFlushCb(() => {
|
||||
if (instance.m) invokeArrayFns(instance.m)
|
||||
instance.isMounted = true
|
||||
// })
|
||||
} else {
|
||||
insert(instance.block, parent, anchor)
|
||||
}
|
||||
}
|
||||
|
||||
export function unmountComponent(
|
||||
instance: VaporComponentInstance,
|
||||
parent: ParentNode,
|
||||
): void {
|
||||
if (instance.isMounted && !instance.isUnmounted) {
|
||||
if (instance.bum) invokeArrayFns(instance.bum)
|
||||
// TODO invoke unmount recursively for children
|
||||
remove(instance.block, parent)
|
||||
// queuePostFlushCb(() => {
|
||||
if (instance.um) invokeArrayFns(instance.um)
|
||||
instance.isUnmounted = true
|
||||
// })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import { invokeArrayFns, isArray } from '@vue/shared'
|
||||
import { isArray } from '@vue/shared'
|
||||
import { renderEffect } from '../renderEffect'
|
||||
import { setText } from './prop'
|
||||
import { type Block, normalizeBlock } from '../block'
|
||||
import { isVaporComponent } from '../component'
|
||||
import type { Block } from '../block'
|
||||
import {
|
||||
isVaporComponent,
|
||||
mountComponent,
|
||||
unmountComponent,
|
||||
} from '../component'
|
||||
|
||||
export function insert(
|
||||
block: Block,
|
||||
|
@ -12,14 +16,7 @@ export function insert(
|
|||
if (block instanceof Node) {
|
||||
parent.insertBefore(block, anchor === 0 ? parent.firstChild : anchor)
|
||||
} else if (isVaporComponent(block)) {
|
||||
if (!block.isMounted) {
|
||||
if (block.bm) invokeArrayFns(block.bm)
|
||||
insert(block.block, parent, anchor)
|
||||
if (block.m) invokeArrayFns(block.m)
|
||||
block.isMounted = true
|
||||
} else {
|
||||
insert(block.block, parent, anchor)
|
||||
}
|
||||
mountComponent(block, parent, anchor)
|
||||
} else if (isArray(block)) {
|
||||
for (let i = 0; i < block.length; i++) {
|
||||
insert(block[i], parent, anchor)
|
||||
|
@ -35,15 +32,23 @@ export function prepend(parent: ParentNode, ...blocks: Block[]): void {
|
|||
for (const b of blocks) insert(b, parent, 0)
|
||||
}
|
||||
|
||||
// TODO optimize
|
||||
// TODO invoke unmount recursive
|
||||
export function remove(block: Block, parent: ParentNode): void {
|
||||
const nodes = normalizeBlock(block)
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
parent.removeChild(nodes[i])
|
||||
if (block instanceof Node) {
|
||||
parent.removeChild(block)
|
||||
} else if (isVaporComponent(block)) {
|
||||
unmountComponent(block, parent)
|
||||
} else if (isArray(block)) {
|
||||
for (let i = 0; i < block.length; i++) {
|
||||
remove(block[i], parent)
|
||||
}
|
||||
} else {
|
||||
// fragment
|
||||
remove(block.nodes, parent)
|
||||
if (block.anchor) remove(block.anchor, parent)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO optimize
|
||||
export function createTextNode(values?: any[] | (() => any[])): Text {
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
const node = document.createTextNode('')
|
||||
|
|
|
@ -19,3 +19,8 @@ export function hmrRerender(instance: VaporComponentInstance): void {
|
|||
popWarningContext()
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue