mirror of https://github.com/vuejs/core.git
wip: vdom in vapor hmr reload
This commit is contained in:
parent
4b12529878
commit
be5c2a2f51
|
@ -3,6 +3,7 @@ import {
|
|||
type ComponentInternalInstance,
|
||||
type ComponentOptions,
|
||||
type ConcreteComponent,
|
||||
type GenericComponentInstance,
|
||||
currentInstance,
|
||||
isInSSRComponentSetup,
|
||||
} from './component'
|
||||
|
@ -39,7 +40,7 @@ export interface AsyncComponentOptions<T = any> {
|
|||
) => any
|
||||
}
|
||||
|
||||
export const isAsyncWrapper = (i: ComponentInternalInstance | VNode): boolean =>
|
||||
export const isAsyncWrapper = (i: GenericComponentInstance | VNode): boolean =>
|
||||
!!(i.type as ComponentOptions).__asyncLoader
|
||||
|
||||
/*! #__NO_SIDE_EFFECTS__ */
|
||||
|
@ -206,10 +207,14 @@ export function defineAsyncComponent<
|
|||
load()
|
||||
.then(() => {
|
||||
loaded.value = true
|
||||
if (instance.parent && isKeepAlive(instance.parent.vnode)) {
|
||||
if (
|
||||
instance.parent &&
|
||||
instance.parent.vnode &&
|
||||
isKeepAlive(instance.parent.vnode)
|
||||
) {
|
||||
// parent is keep-alive, force update so the loaded component's
|
||||
// name is taken into account
|
||||
instance.parent.update()
|
||||
;(instance.parent as ComponentInternalInstance).update()
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
|
|
|
@ -504,6 +504,26 @@ export interface GenericComponentInstance {
|
|||
* @internal vapor only
|
||||
*/
|
||||
hmrReload?: (newComp: any) => void
|
||||
|
||||
// these only exist on vdom instances
|
||||
vnode?: VNode
|
||||
subTree?: VNode
|
||||
|
||||
/**
|
||||
* Custom Element instance (if component is created by defineCustomElement)
|
||||
* @internal
|
||||
*/
|
||||
ce?: ComponentCustomElementInterface
|
||||
/**
|
||||
* is custom element? (kept only for compatibility)
|
||||
* @internal
|
||||
*/
|
||||
isCE?: boolean
|
||||
/**
|
||||
* custom element specific HMR method
|
||||
* @internal
|
||||
*/
|
||||
ceReload?: (newStyles?: string[]) => void
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -514,8 +534,8 @@ export interface ComponentInternalInstance extends GenericComponentInstance {
|
|||
vapor?: never
|
||||
uid: number
|
||||
type: ConcreteComponent
|
||||
parent: ComponentInternalInstance | null
|
||||
root: ComponentInternalInstance
|
||||
parent: GenericComponentInstance | null
|
||||
root: GenericComponentInstance
|
||||
appContext: AppContext
|
||||
/**
|
||||
* Vnode representing this component in its parent's vdom tree
|
||||
|
@ -589,21 +609,6 @@ export interface ComponentInternalInstance extends GenericComponentInstance {
|
|||
* @internal
|
||||
*/
|
||||
inheritAttrs?: boolean
|
||||
/**
|
||||
* Custom Element instance (if component is created by defineCustomElement)
|
||||
* @internal
|
||||
*/
|
||||
ce?: ComponentCustomElementInterface
|
||||
/**
|
||||
* is custom element? (kept only for compatibility)
|
||||
* @internal
|
||||
*/
|
||||
isCE?: boolean
|
||||
/**
|
||||
* custom element specific HMR method
|
||||
* @internal
|
||||
*/
|
||||
ceReload?: (newStyles?: string[]) => void
|
||||
|
||||
// the rest are only for stateful components ---------------------------------
|
||||
/**
|
||||
|
@ -1210,7 +1215,7 @@ export function expose(
|
|||
}
|
||||
|
||||
export function getComponentPublicInstance(
|
||||
instance: ComponentInternalInstance,
|
||||
instance: GenericComponentInstance,
|
||||
): ComponentPublicInstance | ComponentInternalInstance['exposed'] | null {
|
||||
if (instance.exposed) {
|
||||
return (
|
||||
|
|
|
@ -232,7 +232,7 @@ export function initProps(
|
|||
instance.attrs = attrs
|
||||
}
|
||||
|
||||
function isInHmrContext(instance: ComponentInternalInstance | null) {
|
||||
function isInHmrContext(instance: GenericComponentInstance | null) {
|
||||
while (instance) {
|
||||
if (instance.type.__hmrId) return true
|
||||
instance = instance.parent
|
||||
|
|
|
@ -2,6 +2,7 @@ import {
|
|||
type Component,
|
||||
type ComponentInternalInstance,
|
||||
type Data,
|
||||
type GenericComponentInstance,
|
||||
getComponentPublicInstance,
|
||||
isStatefulComponent,
|
||||
} from './component'
|
||||
|
@ -355,10 +356,11 @@ export type PublicPropertiesMap = Record<
|
|||
* public $parent chains, skip functional ones and go to the parent instead.
|
||||
*/
|
||||
const getPublicInstance = (
|
||||
i: ComponentInternalInstance | null,
|
||||
i: GenericComponentInstance | null,
|
||||
): ComponentPublicInstance | ComponentInternalInstance['exposed'] | null => {
|
||||
if (!i) return null
|
||||
if (isStatefulComponent(i)) return getComponentPublicInstance(i)
|
||||
if (!i || i.vapor) return null
|
||||
if (isStatefulComponent(i as ComponentInternalInstance))
|
||||
return getComponentPublicInstance(i)
|
||||
return getPublicInstance(i.parent)
|
||||
}
|
||||
|
||||
|
|
|
@ -455,12 +455,12 @@ export function updateHOCHostEl(
|
|||
el: typeof vnode.el, // HostNode
|
||||
): void {
|
||||
while (parent && !parent.vapor) {
|
||||
const root = parent.subTree
|
||||
const root = parent.subTree!
|
||||
if (root.suspense && root.suspense.activeBranch === vnode) {
|
||||
root.el = vnode.el
|
||||
}
|
||||
if (root === vnode) {
|
||||
;(vnode = parent.vnode).el = el
|
||||
;(vnode = parent.vnode!).el = el
|
||||
parent = parent.parent
|
||||
} else {
|
||||
break
|
||||
|
|
|
@ -2,6 +2,7 @@ import {
|
|||
type ComponentInternalInstance,
|
||||
type ComponentOptions,
|
||||
type ConcreteComponent,
|
||||
type GenericComponentInstance,
|
||||
type SetupContext,
|
||||
getComponentName,
|
||||
getCurrentInstance,
|
||||
|
@ -436,7 +437,7 @@ function registerKeepAliveHook(
|
|||
hook.__wdc ||
|
||||
(hook.__wdc = () => {
|
||||
// only fire the hook if the target instance is NOT in a deactivated branch.
|
||||
let current: ComponentInternalInstance | null = target
|
||||
let current: GenericComponentInstance | null = target
|
||||
while (current) {
|
||||
if (current.isDeactivated) {
|
||||
return
|
||||
|
@ -453,7 +454,7 @@ function registerKeepAliveHook(
|
|||
// arrays.
|
||||
if (target) {
|
||||
let current = target.parent
|
||||
while (current && current.parent) {
|
||||
while (current && current.parent && current.parent.vnode) {
|
||||
if (isKeepAlive(current.parent.vnode)) {
|
||||
injectToKeepAliveRoot(wrappedHook, type, target, current)
|
||||
}
|
||||
|
@ -466,7 +467,7 @@ function injectToKeepAliveRoot(
|
|||
hook: Function & { __weh?: Function },
|
||||
type: LifecycleHooks,
|
||||
target: ComponentInternalInstance,
|
||||
keepAliveRoot: ComponentInternalInstance,
|
||||
keepAliveRoot: GenericComponentInstance,
|
||||
) {
|
||||
// injectHook wraps the original for error handling, so make sure to remove
|
||||
// the wrapped version.
|
||||
|
|
|
@ -154,7 +154,12 @@ function reload(id: string, newComp: HMRComponent): void {
|
|||
// don't end up forcing the same parent to re-render multiple times.
|
||||
queueJob(() => {
|
||||
isHmrUpdating = true
|
||||
instance.parent!.update()
|
||||
const parent = instance.parent!
|
||||
if (parent.vapor) {
|
||||
parent.hmrRerender!()
|
||||
} else {
|
||||
;(parent as ComponentInternalInstance).update()
|
||||
}
|
||||
isHmrUpdating = false
|
||||
// #6930, #11248 avoid infinite recursion
|
||||
dirtyInstances.delete(instance)
|
||||
|
|
|
@ -768,7 +768,7 @@ export function createHydrationFunctions(
|
|||
if (parent.vnode.el === oldNode) {
|
||||
parent.vnode.el = parent.subTree.el = newNode
|
||||
}
|
||||
parent = parent.parent
|
||||
parent = parent.parent as ComponentInternalInstance
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -945,7 +945,11 @@ function resolveCssVars(
|
|||
}
|
||||
}
|
||||
if (vnode === root && instance.parent) {
|
||||
resolveCssVars(instance.parent, instance.vnode, expectedMap)
|
||||
resolveCssVars(
|
||||
instance.parent as ComponentInternalInstance,
|
||||
instance.vnode,
|
||||
expectedMap,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
type ComponentOptions,
|
||||
type ConcreteComponent,
|
||||
type Data,
|
||||
type GenericComponentInstance,
|
||||
type LifecycleHook,
|
||||
createComponentInstance,
|
||||
getComponentPublicInstance,
|
||||
|
@ -749,7 +750,7 @@ function baseCreateRenderer(
|
|||
vnode: VNode,
|
||||
scopeId: string | null,
|
||||
slotScopeIds: string[] | null,
|
||||
parentComponent: ComponentInternalInstance | null,
|
||||
parentComponent: GenericComponentInstance | null,
|
||||
) => {
|
||||
if (scopeId) {
|
||||
hostSetScopeId(el, scopeId)
|
||||
|
@ -774,7 +775,7 @@ function baseCreateRenderer(
|
|||
(isSuspense(subTree.type) &&
|
||||
(subTree.ssContent === vnode || subTree.ssFallback === vnode))
|
||||
) {
|
||||
const parentVNode = parentComponent!.vnode
|
||||
const parentVNode = parentComponent!.vnode!
|
||||
setScopeId(
|
||||
el,
|
||||
parentVNode,
|
||||
|
@ -1382,8 +1383,8 @@ function baseCreateRenderer(
|
|||
}
|
||||
} else {
|
||||
// custom element style injection
|
||||
if (root.ce) {
|
||||
root.ce._injectChildStyle(type)
|
||||
if ((root as ComponentInternalInstance).ce) {
|
||||
;(root as ComponentInternalInstance).ce!._injectChildStyle(type)
|
||||
}
|
||||
|
||||
if (__DEV__) {
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
type ComponentInternalInstance,
|
||||
type ConcreteComponent,
|
||||
type Data,
|
||||
type GenericComponentInstance,
|
||||
isClassComponent,
|
||||
} from './component'
|
||||
import type { RawSlots } from './componentSlots'
|
||||
|
@ -903,7 +904,7 @@ export function mergeProps(...args: (Data & VNodeProps)[]): Data {
|
|||
|
||||
export function invokeVNodeHook(
|
||||
hook: VNodeHook,
|
||||
instance: ComponentInternalInstance | null,
|
||||
instance: GenericComponentInstance | null,
|
||||
vnode: VNode,
|
||||
prevVNode: VNode | null = null,
|
||||
): void {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import {
|
||||
type ComponentInternalInstance,
|
||||
type Data,
|
||||
type GenericComponentInstance,
|
||||
formatComponentName,
|
||||
|
@ -106,9 +105,9 @@ export function getComponentTrace(): ComponentTraceStack {
|
|||
})
|
||||
}
|
||||
if (isVNode(currentCtx)) {
|
||||
const parent: ComponentInternalInstance | null =
|
||||
const parent: GenericComponentInstance | null =
|
||||
currentCtx.component && currentCtx.component.parent
|
||||
currentCtx = parent && parent.vnode
|
||||
currentCtx = (parent && parent.vnode) || parent
|
||||
} else {
|
||||
currentCtx = currentCtx.parent
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import {
|
|||
vtcKey,
|
||||
} from './Transition'
|
||||
import {
|
||||
type ComponentInternalInstance,
|
||||
type ComponentOptions,
|
||||
DeprecationTypes,
|
||||
Fragment,
|
||||
|
@ -122,7 +123,7 @@ const TransitionGroupImpl: ComponentOptions = /*@__PURE__*/ decorate({
|
|||
!rawProps.tag &&
|
||||
compatUtils.checkCompatEnabled(
|
||||
DeprecationTypes.TRANSITION_GROUP_ROOT,
|
||||
instance.parent,
|
||||
instance.parent as ComponentInternalInstance,
|
||||
)
|
||||
) {
|
||||
tag = 'span'
|
||||
|
|
|
@ -172,7 +172,7 @@ function renderComponentSubTree(
|
|||
if (parent && parent.subTree && parent.subTree === cur.vnode) {
|
||||
// parent is a non-SSR compiled component and is rendering this
|
||||
// component as root. inherit its scopeId if present.
|
||||
cur = parent
|
||||
cur = parent as ComponentInternalInstance
|
||||
} else {
|
||||
break
|
||||
}
|
||||
|
@ -314,7 +314,7 @@ function renderElementVNode(
|
|||
if (curVnode.scopeId) {
|
||||
openTag += ` ${curVnode.scopeId}`
|
||||
}
|
||||
curParent = curParent.parent
|
||||
curParent = curParent.parent as ComponentInternalInstance
|
||||
}
|
||||
if (slotScopeId) {
|
||||
openTag += ` ${slotScopeId}`
|
||||
|
|
Loading…
Reference in New Issue