Skip to content

Commit c40f604

Browse files
committed
wip: refactor
1 parent 7ca7ef0 commit c40f604

File tree

4 files changed

+75
-55
lines changed

4 files changed

+75
-55
lines changed

packages/reactivity/src/effectScope.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ export class EffectScope implements ReactiveNode {
8787
if (sub !== undefined) {
8888
unlink(sub)
8989
}
90+
this.cleanup()
91+
}
92+
93+
/**
94+
* @internal
95+
*/
96+
cleanup(): void {
9097
cleanup(this)
9198
}
9299
}

packages/runtime-vapor/src/component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ import {
5858
} from './componentSlots'
5959
import { hmrReload, hmrRerender } from './hmr'
6060
import { isHydrating, locateHydrationNode } from './dom/hydration'
61-
import { isVaporTeleport } from './components/Teleport'
61+
import { type TeleportFragment, isVaporTeleport } from './components/Teleport'
6262
import {
6363
insertionAnchor,
6464
insertionParent,
@@ -405,8 +405,8 @@ export class VaporComponentInstance implements GenericComponentInstance {
405405
setupState?: Record<string, any>
406406
devtoolsRawSetupState?: any
407407
hmrRerender?: () => void
408-
hmrRerenderEffects?: (() => void)[]
409408
hmrReload?: (newComp: VaporComponent) => void
409+
parentTeleport?: TeleportFragment | null
410410
propsOptions?: NormalizedPropsOptions
411411
emitsOptions?: ObjectEmitsOptions | null
412412
isSingleRoot?: boolean

packages/runtime-vapor/src/components/Teleport.ts

Lines changed: 7 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import {
22
type TeleportProps,
3-
currentInstance,
43
isTeleportDeferred,
54
isTeleportDisabled,
5+
onScopeDispose,
66
queuePostFlushCb,
77
resolveTeleportTarget,
88
warn,
@@ -12,29 +12,25 @@ import { createComment, createTextNode, querySelector } from '../dom/node'
1212
import {
1313
type LooseRawProps,
1414
type LooseRawSlots,
15-
type VaporComponentInstance,
1615
isVaporComponent,
1716
} from '../component'
1817
import { rawPropsProxyHandlers } from '../componentProps'
1918
import { renderEffect } from '../renderEffect'
2019
import { extend, isArray } from '@vue/shared'
2120
import { VaporFragment } from '../fragment'
2221

23-
const instanceToTeleportMap: WeakMap<VaporComponentInstance, TeleportFragment> =
24-
__DEV__ ? new WeakMap() : (undefined as any)
25-
2622
export const VaporTeleportImpl = {
2723
name: 'VaporTeleport',
2824
__isTeleport: true,
2925
__vapor: true,
3026

3127
process(props: LooseRawProps, slots: LooseRawSlots): TeleportFragment {
3228
const frag = new TeleportFragment()
33-
const updateChildrenEffect = renderEffect(() =>
29+
renderEffect(() =>
3430
frag.updateChildren(slots.default && (slots.default as BlockFn)()),
3531
)
3632

37-
const updateEffect = renderEffect(() => {
33+
renderEffect(() => {
3834
// access the props to trigger tracking
3935
frag.props = extend(
4036
{},
@@ -43,6 +39,8 @@ export const VaporTeleportImpl = {
4339
frag.update()
4440
})
4541

42+
onScopeDispose(frag.remove)
43+
4644
if (__DEV__) {
4745
// used in `normalizeBlock` to get nodes of TeleportFragment during
4846
// HMR updates. returns empty array if content is mounted in target
@@ -51,27 +49,12 @@ export const VaporTeleportImpl = {
5149
return frag.parent !== frag.currentParent ? [] : frag.nodes
5250
}
5351

54-
// for HMR rerender
55-
const instance = currentInstance as VaporComponentInstance
56-
;(
57-
instance!.hmrRerenderEffects || (instance!.hmrRerenderEffects = [])
58-
).push(() => {
59-
// remove the teleport content
60-
frag.remove()
61-
62-
// stop effects
63-
updateChildrenEffect.stop()
64-
updateEffect.stop()
65-
})
66-
67-
// for HMR reload
6852
const nodes = frag.nodes
6953
if (isVaporComponent(nodes)) {
70-
instanceToTeleportMap.set(nodes, frag)
54+
nodes.parentTeleport = frag
7155
} else if (isArray(nodes)) {
7256
nodes.forEach(
73-
node =>
74-
isVaporComponent(node) && instanceToTeleportMap.set(node, frag),
57+
node => isVaporComponent(node) && (node.parentTeleport = frag),
7558
)
7659
}
7760
}
@@ -221,25 +204,3 @@ export function isVaporTeleport(
221204
): value is typeof VaporTeleportImpl {
222205
return value === VaporTeleportImpl
223206
}
224-
225-
/**
226-
* dev only
227-
* during root component HMR reload, since the old component will be unmounted
228-
* and a new one will be mounted, we need to update the teleport's nodes
229-
* to ensure they are up to date.
230-
*/
231-
export function handleTeleportRootComponentHmrReload(
232-
instance: VaporComponentInstance,
233-
newInstance: VaporComponentInstance,
234-
): void {
235-
const teleport = instanceToTeleportMap.get(instance)
236-
if (teleport) {
237-
instanceToTeleportMap.set(newInstance, teleport)
238-
if (teleport.nodes === instance) {
239-
teleport.nodes = newInstance
240-
} else if (isArray(teleport.nodes)) {
241-
const i = teleport.nodes.indexOf(instance)
242-
if (i !== -1) teleport.nodes[i] = newInstance
243-
}
244-
}
245-
}

packages/runtime-vapor/src/hmr.ts

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,14 @@ import {
1212
mountComponent,
1313
unmountComponent,
1414
} from './component'
15-
import { handleTeleportRootComponentHmrReload } from './components/Teleport'
15+
import { isArray } from '@vue/shared'
1616

1717
export function hmrRerender(instance: VaporComponentInstance): void {
1818
const normalized = normalizeBlock(instance.block)
1919
const parent = normalized[0].parentNode!
2020
const anchor = normalized[normalized.length - 1].nextSibling
2121
remove(instance.block, parent)
22-
if (instance.hmrRerenderEffects) {
23-
instance.hmrRerenderEffects.forEach(e => e())
24-
instance.hmrRerenderEffects.length = 0
25-
}
22+
instance.scope.cleanup()
2623
const prev = setCurrentInstance(instance)
2724
pushWarningContext(instance)
2825
devRender(instance)
@@ -39,7 +36,8 @@ export function hmrReload(
3936
const parent = normalized[0].parentNode!
4037
const anchor = normalized[normalized.length - 1].nextSibling
4138
unmountComponent(instance, parent)
42-
const prev = setCurrentInstance(instance.parent)
39+
const parentInstance = instance.parent as VaporComponentInstance | null
40+
const prev = setCurrentInstance(parentInstance)
4341
const newInstance = createComponent(
4442
newComp,
4543
instance.rawProps,
@@ -48,5 +46,59 @@ export function hmrReload(
4846
)
4947
setCurrentInstance(...prev)
5048
mountComponent(newInstance, parent, anchor)
51-
handleTeleportRootComponentHmrReload(instance, newInstance)
49+
50+
updateParentBlockOnHmrReload(parentInstance, instance, newInstance)
51+
updateParentTeleportOnHmrReload(instance, newInstance)
52+
}
53+
54+
/**
55+
* dev only
56+
* update parentInstance.block to ensure that the correct parent and
57+
* anchor are found during parentInstance HMR rerender/reload, as
58+
* `normalizeBlock` relies on the current instance.block
59+
*/
60+
function updateParentBlockOnHmrReload(
61+
parentInstance: VaporComponentInstance | null,
62+
instance: VaporComponentInstance,
63+
newInstance: VaporComponentInstance,
64+
): void {
65+
if (parentInstance) {
66+
if (parentInstance.block === instance) {
67+
parentInstance.block = newInstance
68+
} else if (isArray(parentInstance.block)) {
69+
for (let i = 0; i < parentInstance.block.length; i++) {
70+
if (parentInstance.block[i] === instance) {
71+
parentInstance.block[i] = newInstance
72+
break
73+
}
74+
}
75+
}
76+
}
77+
}
78+
79+
/**
80+
* dev only
81+
* during root component HMR reload, since the old component will be unmounted
82+
* and a new one will be mounted, we need to update the teleport's nodes
83+
* to ensure that the correct parent and anchor are found during parentInstance
84+
* HMR rerender/reload, as `normalizeBlock` relies on the current instance.block
85+
*/
86+
export function updateParentTeleportOnHmrReload(
87+
instance: VaporComponentInstance,
88+
newInstance: VaporComponentInstance,
89+
): void {
90+
const teleport = instance.parentTeleport
91+
if (teleport) {
92+
newInstance.parentTeleport = teleport
93+
if (teleport.nodes === instance) {
94+
teleport.nodes = newInstance
95+
} else if (isArray(teleport.nodes)) {
96+
for (let i = 0; i < teleport.nodes.length; i++) {
97+
if (teleport.nodes[i] === instance) {
98+
teleport.nodes[i] = newInstance
99+
break
100+
}
101+
}
102+
}
103+
}
52104
}

0 commit comments

Comments
 (0)