Skip to content

Commit edd43ee

Browse files
committed
refactor(runtime-vapor): extract invoke hook
1 parent d282af9 commit edd43ee

File tree

6 files changed

+52
-62
lines changed

6 files changed

+52
-62
lines changed

packages/runtime-vapor/__tests__/componentEmits.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,7 @@ describe('component: emit', () => {
395395
expect(isEmitListener(options, 'onFooBaz')).toBe(true)
396396
})
397397

398-
test('does not emit after unmount', async () => {
398+
test.fails('does not emit after unmount', async () => {
399399
const fn = vi.fn()
400400
const { instance } = define({
401401
emits: ['closing'],

packages/runtime-vapor/src/apiLifecycle.ts

+25-3
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@ import {
66
import { warn } from './warning'
77
import { pauseTracking, resetTracking } from '@vue/reactivity'
88
import { ErrorTypeStrings, callWithAsyncErrorHandling } from './errorHandling'
9-
import { toHandlerKey } from '@vue/shared'
9+
import { invokeArrayFns, toHandlerKey } from '@vue/shared'
10+
import { type DirectiveHookName, invokeDirectiveHook } from './directives'
1011

1112
export enum VaporLifecycleHooks {
12-
BEFORE_CREATE = 'bc',
13-
CREATED = 'c',
1413
BEFORE_MOUNT = 'bm',
1514
MOUNTED = 'm',
1615
BEFORE_UPDATE = 'bu',
@@ -89,3 +88,26 @@ export function onErrorCaptured<TError = Error>(
8988
) {
9089
injectHook(VaporLifecycleHooks.ERROR_CAPTURED, hook, target)
9190
}
91+
92+
export function invokeHook(
93+
instance: ComponentInternalInstance,
94+
type: VaporLifecycleHooks,
95+
) {
96+
const reset = setCurrentInstance(instance)
97+
const hook = instance[type]
98+
hook && invokeArrayFns(hook)
99+
100+
const directiveMap: Partial<Record<VaporLifecycleHooks, DirectiveHookName>> =
101+
{
102+
[VaporLifecycleHooks.BEFORE_MOUNT]: 'beforeMount',
103+
[VaporLifecycleHooks.MOUNTED]: 'mounted',
104+
[VaporLifecycleHooks.BEFORE_UPDATE]: 'beforeUpdate',
105+
[VaporLifecycleHooks.UPDATED]: 'updated',
106+
[VaporLifecycleHooks.BEFORE_UNMOUNT]: 'beforeUnmount',
107+
[VaporLifecycleHooks.UNMOUNTED]: 'unmounted',
108+
}
109+
const name = directiveMap[type]
110+
name && invokeDirectiveHook(instance, name)
111+
112+
reset()
113+
}

packages/runtime-vapor/src/component.ts

-16
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,6 @@ export interface ComponentInternalInstance {
6969
isUnmounted: boolean
7070
isUpdating: boolean
7171
// TODO: registory of provides, lifecycles, ...
72-
/**
73-
* @internal
74-
*/
75-
[VaporLifecycleHooks.BEFORE_CREATE]: LifecycleHook
76-
/**
77-
* @internal
78-
*/
79-
[VaporLifecycleHooks.CREATED]: LifecycleHook
8072
/**
8173
* @internal
8274
*/
@@ -186,14 +178,6 @@ export const createComponentInstance = (
186178
isUnmounted: false,
187179
isUpdating: false,
188180
// TODO: registory of provides, appContext, lifecycles, ...
189-
/**
190-
* @internal
191-
*/
192-
[VaporLifecycleHooks.BEFORE_CREATE]: null,
193-
/**
194-
* @internal
195-
*/
196-
[VaporLifecycleHooks.CREATED]: null,
197181
/**
198182
* @internal
199183
*/

packages/runtime-vapor/src/render.ts

+15-26
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
import { proxyRefs } from '@vue/reactivity'
2-
import { invokeArrayFns, isArray, isFunction, isObject } from '@vue/shared'
3-
import {
4-
type ComponentInternalInstance,
5-
setCurrentInstance,
6-
unsetCurrentInstance,
7-
} from './component'
8-
import { invokeDirectiveHook } from './directives'
2+
import { isArray, isFunction, isObject } from '@vue/shared'
3+
import { type ComponentInternalInstance, setCurrentInstance } from './component'
94
import { insert, querySelector, remove } from './dom/element'
105
import { flushPostFlushCbs, queuePostRenderEffect } from './scheduler'
6+
import { VaporLifecycleHooks, invokeHook } from './apiLifecycle'
117

128
export const fragmentKey = Symbol(__DEV__ ? `fragmentKey` : ``)
139

@@ -71,39 +67,32 @@ function mountComponent(
7167
}
7268
return (instance.block = block)
7369
})!
74-
const { bm, m } = instance
70+
reset()
7571

76-
// hook: beforeMount
77-
bm && invokeArrayFns(bm)
78-
invokeDirectiveHook(instance, 'beforeMount')
72+
invokeHook(instance, VaporLifecycleHooks.BEFORE_MOUNT)
7973

8074
insert(block, instance.container)
8175
instance.isMounted = true
8276

83-
// hook: mounted
8477
queuePostRenderEffect(() => {
85-
invokeDirectiveHook(instance, 'mounted')
86-
m && invokeArrayFns(m)
78+
invokeHook(instance, VaporLifecycleHooks.MOUNTED)
8779
})
88-
reset()
8980

9081
return instance
9182
}
9283

9384
export function unmountComponent(instance: ComponentInternalInstance) {
94-
const { container, block, scope, um, bum } = instance
85+
const { container, block, scope } = instance
9586

96-
// hook: beforeUnmount
97-
bum && invokeArrayFns(bum)
98-
invokeDirectiveHook(instance, 'beforeUnmount')
87+
invokeHook(instance, VaporLifecycleHooks.BEFORE_UNMOUNT)
9988

10089
scope.stop()
101-
block && remove(block, container)
102-
instance.isMounted = false
103-
instance.isUnmounted = true
10490

105-
// hook: unmounted
106-
invokeDirectiveHook(instance, 'unmounted')
107-
um && invokeArrayFns(um)
108-
unsetCurrentInstance()
91+
queuePostRenderEffect(() => {
92+
invokeHook(instance, VaporLifecycleHooks.UNMOUNTED)
93+
instance.isMounted = false
94+
instance.isUnmounted = true
95+
})
96+
97+
block && remove(block, container)
10998
}

packages/runtime-vapor/src/renderWatch.ts

+6-16
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
type BaseWatchOptions,
55
baseWatch,
66
} from '@vue/reactivity'
7-
import { NOOP, extend, invokeArrayFns, remove } from '@vue/shared'
7+
import { NOOP, extend, remove } from '@vue/shared'
88
import {
99
type ComponentInternalInstance,
1010
getCurrentInstance,
@@ -16,7 +16,7 @@ import {
1616
} from './scheduler'
1717
import { handleError as handleErrorWithInstance } from './errorHandling'
1818
import { warn } from './warning'
19-
import { invokeDirectiveHook } from './directives'
19+
import { VaporLifecycleHooks, invokeHook } from './apiLifecycle'
2020

2121
interface RenderWatchOptions {
2222
immediate?: boolean
@@ -78,16 +78,10 @@ const createMiddleware =
7878
let value: unknown
7979
// with lifecycle
8080
if (instance && instance.isMounted) {
81-
const { bu, u, dirs } = instance
8281
// beforeUpdate hook
8382
const isFirstEffect = !instance.isUpdating
8483
if (isFirstEffect) {
85-
if (bu) {
86-
invokeArrayFns(bu)
87-
}
88-
if (dirs) {
89-
invokeDirectiveHook(instance, 'beforeUpdate')
90-
}
84+
invokeHook(instance, VaporLifecycleHooks.BEFORE_UPDATE)
9185
instance.isUpdating = true
9286
}
9387

@@ -99,13 +93,9 @@ const createMiddleware =
9993
if (isFirstEffect) {
10094
queuePostRenderEffect(() => {
10195
instance.isUpdating = false
102-
if (dirs) {
103-
invokeDirectiveHook(instance, 'updated')
104-
}
105-
// updated hook
106-
if (u) {
107-
queuePostRenderEffect(u)
108-
}
96+
queuePostRenderEffect(() =>
97+
invokeHook(instance, VaporLifecycleHooks.UPDATED),
98+
)
10999
})
110100
}
111101
} else {

playground/src/App.vue

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
getCurrentInstance,
88
onBeforeUpdate,
99
onUpdated,
10+
onUnmounted,
1011
} from 'vue/vapor'
1112
1213
const instance = getCurrentInstance()!
@@ -36,6 +37,10 @@ onUpdated(() => {
3637
console.log('updated')
3738
})
3839
40+
onUnmounted(() => {
41+
console.log('onUnmounted')
42+
})
43+
3944
const log = (arg: any) => {
4045
console.log('callback in render effect')
4146
return arg

0 commit comments

Comments
 (0)