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