Skip to content

Commit 818ccb6

Browse files
committed
refactor: cleaning up the code
1 parent b3e07b4 commit 818ccb6

9 files changed

+98
-118
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,13 @@
1-
import {
2-
type Component,
3-
createComponentInstance,
4-
setCurrentInstance,
5-
} from './component'
1+
import { type Component, createComponentInstance } from './component'
62
import { setupComponent } from './apiRender'
73
import type { RawProps } from './componentProps'
84
import type { RawSlots } from './componentSlots'
95
import { withAttrs } from './componentAttrs'
106
import { getCurrentScope } from '@vue/reactivity'
117
import type { BlockEffectScope } from './blockEffectScope'
12-
import {
13-
type Directive,
14-
type DirectiveHookName,
15-
invokeDirectiveHook,
16-
} from './directives'
8+
import { setDirectiveBinding } from './directives'
179
import { VaporLifecycleHooks } from './enums'
18-
import { NOOP, invokeArrayFns } from '@vue/shared'
10+
import { scheduleLifecycleHooks } from './componentLifecycle'
1911

2012
export function createComponent(
2113
comp: Component,
@@ -33,58 +25,39 @@ export function createComponent(
3325
)
3426
setupComponent(instance, singleRoot)
3527

36-
const directiveBindingsMap = (parentScope.dirs ||= new Map())
37-
const dir: Directive = {
38-
beforeMount: passDirectives(
39-
VaporLifecycleHooks.BEFORE_MOUNT,
40-
'beforeMount',
41-
),
42-
mounted: passDirectives(
43-
VaporLifecycleHooks.MOUNTED,
44-
'mounted',
45-
() => (instance.isMounted = true),
46-
true,
47-
),
48-
beforeUnmount: passDirectives(
49-
VaporLifecycleHooks.BEFORE_UNMOUNT,
50-
'beforeUnmount',
51-
),
52-
unmounted: passDirectives(
53-
VaporLifecycleHooks.UNMOUNTED,
54-
'unmounted',
55-
() => (instance.isUnmounted = true),
56-
true,
57-
),
58-
}
59-
directiveBindingsMap.set(instance, [
60-
{ dir, instance, value: null, oldValue: undefined },
61-
])
28+
setDirectiveBinding(
29+
instance,
30+
instance,
31+
{
32+
beforeMount: scheduleLifecycleHooks(
33+
instance,
34+
VaporLifecycleHooks.BEFORE_MOUNT,
35+
'beforeMount',
36+
),
37+
mounted: scheduleLifecycleHooks(
38+
instance,
39+
VaporLifecycleHooks.MOUNTED,
40+
'mounted',
41+
() => (instance.isMounted = true),
42+
true,
43+
),
44+
beforeUnmount: scheduleLifecycleHooks(
45+
instance,
46+
VaporLifecycleHooks.BEFORE_UNMOUNT,
47+
'beforeUnmount',
48+
),
49+
unmounted: scheduleLifecycleHooks(
50+
instance,
51+
VaporLifecycleHooks.UNMOUNTED,
52+
'unmounted',
53+
() => (instance.isUnmounted = true),
54+
true,
55+
),
56+
},
57+
null,
58+
undefined,
59+
parentScope,
60+
)
6261

6362
return instance
64-
65-
function passDirectives(
66-
lifecycle: VaporLifecycleHooks,
67-
directive: DirectiveHookName,
68-
cb = NOOP,
69-
reverse?: boolean,
70-
) {
71-
const hooks = reverse
72-
? [cb, callDirHooks, callLifecycleHooks]
73-
: [callLifecycleHooks, callDirHooks, cb]
74-
75-
return () => invokeArrayFns(hooks)
76-
77-
function callDirHooks() {
78-
invokeDirectiveHook(instance, directive, instance.scope)
79-
}
80-
function callLifecycleHooks() {
81-
// lifecycle hooks may be mounted halfway.
82-
const lifecycleHooks = instance[lifecycle]
83-
if (lifecycleHooks && lifecycleHooks.length) {
84-
const reset = setCurrentInstance(instance)
85-
instance.scope.run(() => invokeArrayFns(lifecycleHooks))
86-
reset()
87-
}
88-
}
89-
}
9063
}

packages/runtime-vapor/src/apiCreateFor.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { type Block, type Fragment, fragmentKey } from './apiRender'
1818
import { warn } from './warning'
1919
import { currentInstance } from './component'
2020
import { componentKey } from './component'
21-
import { BlockEffectScope, isRenderEffectScope } from './blockEffectScope'
21+
import { BlockEffectScope, isBlockEffectScope } from './blockEffectScope'
2222
import {
2323
createChildFragmentDirectives,
2424
invokeWithMount,
@@ -62,7 +62,7 @@ export const createFor = (
6262
}
6363

6464
const instance = currentInstance!
65-
if (__DEV__ && (!instance || !isRenderEffectScope(parentScope))) {
65+
if (__DEV__ && (!instance || !isBlockEffectScope(parentScope))) {
6666
warn('createFor() can only be used inside setup()')
6767
}
6868

packages/runtime-vapor/src/apiCreateIf.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { getCurrentScope } from '@vue/reactivity'
33
import { createComment, createTextNode, insert, remove } from './dom/element'
44
import { currentInstance } from './component'
55
import { warn } from './warning'
6-
import { BlockEffectScope, isRenderEffectScope } from './blockEffectScope'
6+
import { BlockEffectScope, isBlockEffectScope } from './blockEffectScope'
77
import {
88
createChildFragmentDirectives,
99
invokeWithMount,
@@ -36,7 +36,7 @@ export const createIf = (
3636
}
3737

3838
const instance = currentInstance!
39-
if (__DEV__ && (!instance || !isRenderEffectScope(parentScope))) {
39+
if (__DEV__ && (!instance || !isBlockEffectScope(parentScope))) {
4040
warn('createIf() can only be used inside setup()')
4141
}
4242

packages/runtime-vapor/src/apiRender.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ function mountComponent(
137137
instance,
138138
VaporLifecycleHooks.MOUNTED,
139139
'mounted',
140-
instance => (instance.isMounted = true),
140+
() => (instance.isMounted = true),
141141
true,
142142
)
143143

@@ -166,7 +166,7 @@ export function unmountComponent(instance: ComponentInternalInstance) {
166166
instance,
167167
VaporLifecycleHooks.UNMOUNTED,
168168
'unmounted',
169-
instance => queuePostFlushCb(() => (instance.isUnmounted = true)),
169+
() => (instance.isUnmounted = true),
170170
true,
171171
)
172172
flushPostFlushCbs()

packages/runtime-vapor/src/blockEffectScope.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class BlockEffectScope extends EffectScope {
2929
}
3030
}
3131

32-
export function isRenderEffectScope(
32+
export function isBlockEffectScope(
3333
scope: EffectScope | undefined,
3434
): scope is BlockEffectScope {
3535
return scope instanceof BlockEffectScope

packages/runtime-vapor/src/component.ts

-2
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,6 @@ export interface ComponentInternalInstance {
162162

163163
provides: Data
164164
scope: BlockEffectScope
165-
comps: Set<ComponentInternalInstance>
166165

167166
rawProps: NormalizedRawProps
168167
propsOptions: NormalizedPropsOptions
@@ -286,7 +285,6 @@ export function createComponentInstance(
286285
scope: null!,
287286
provides: parent ? parent.provides : Object.create(_appContext.provides),
288287
type: component,
289-
comps: new Set(),
290288

291289
// resolved props and emits options
292290
rawProps: null!, // set later
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,43 @@
1-
import { invokeArrayFns } from '@vue/shared'
1+
import { NOOP, invokeArrayFns } from '@vue/shared'
22
import type { VaporLifecycleHooks } from './enums'
33
import { type ComponentInternalInstance, setCurrentInstance } from './component'
4-
import { queuePostFlushCb } from './scheduler'
54
import { type DirectiveHookName, invokeDirectiveHook } from './directives'
5+
import { queuePostFlushCb } from './scheduler'
66

77
export function invokeLifecycle(
88
instance: ComponentInternalInstance,
99
lifecycle: VaporLifecycleHooks,
1010
directive: DirectiveHookName,
11-
cb?: (instance: ComponentInternalInstance) => void,
11+
cb?: () => void,
1212
post?: boolean,
1313
) {
14-
invokeArrayFns(post ? [invokeSub, invokeCurrent] : [invokeCurrent, invokeSub])
14+
const fn = scheduleLifecycleHooks(instance, lifecycle, directive, cb, post)
15+
return post ? queuePostFlushCb(fn) : fn()
16+
}
1517

16-
function invokeCurrent() {
17-
cb && cb(instance)
18-
const hooks = instance[lifecycle]
19-
if (hooks) {
20-
const fn = () => {
21-
const reset = setCurrentInstance(instance)
22-
instance.scope.run(() => invokeArrayFns(hooks))
23-
reset()
24-
}
25-
post ? queuePostFlushCb(fn) : fn()
26-
}
18+
export function scheduleLifecycleHooks(
19+
instance: ComponentInternalInstance,
20+
lifecycle: VaporLifecycleHooks,
21+
directive: DirectiveHookName,
22+
cb = NOOP,
23+
reverse?: boolean,
24+
) {
25+
const hooks = reverse
26+
? [cb, callDirHooks, callLifecycleHooks]
27+
: [callLifecycleHooks, callDirHooks, cb]
28+
29+
return () => invokeArrayFns(hooks)
2730

31+
function callDirHooks() {
2832
invokeDirectiveHook(instance, directive, instance.scope)
2933
}
30-
31-
function invokeSub() {
32-
instance.comps.forEach(comp =>
33-
invokeLifecycle(comp, lifecycle, directive, cb, post),
34-
)
34+
function callLifecycleHooks() {
35+
// lifecycle hooks may be mounted halfway.
36+
const lifecycleHooks = instance[lifecycle]
37+
if (lifecycleHooks && lifecycleHooks.length) {
38+
const reset = setCurrentInstance(instance)
39+
instance.scope.run(() => invokeArrayFns(lifecycleHooks))
40+
reset()
41+
}
3542
}
3643
}

packages/runtime-vapor/src/directives.ts

+20-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
} from './errorHandling'
2222
import { queueJob, queuePostFlushCb } from './scheduler'
2323
import { warn } from './warning'
24-
import { type BlockEffectScope, isRenderEffectScope } from './blockEffectScope'
24+
import { type BlockEffectScope, isBlockEffectScope } from './blockEffectScope'
2525
import { normalizeBlock } from './dom/element'
2626

2727
export type DirectiveModifiers<M extends string = string> = Record<M, boolean>
@@ -112,8 +112,8 @@ export function withDirectives<T extends ComponentInternalInstance | Node>(
112112
const instance = currentInstance!
113113
const parentScope = getCurrentScope() as BlockEffectScope
114114

115-
if (__DEV__ && !isRenderEffectScope(parentScope)) {
116-
warn(`Directives should be used inside of RenderEffectScope.`)
115+
if (__DEV__ && !isBlockEffectScope(parentScope)) {
116+
warn(`Directives should be used inside of BlockEffectScope.`)
117117
}
118118

119119
const directivesMap = (parentScope.dirs ||= new Map())
@@ -264,3 +264,20 @@ export function createRenderingUpdateTrigger(
264264
}
265265
}
266266
}
267+
268+
/** For internal use, set directive binding */
269+
export function setDirectiveBinding(
270+
instance: ComponentInternalInstance | null,
271+
anchor: Node | ComponentInternalInstance,
272+
dir: Directive,
273+
value: any = null,
274+
oldValue: any = undefined,
275+
parentScope = getCurrentScope() as BlockEffectScope,
276+
) {
277+
if (__DEV__ && !isBlockEffectScope(parentScope)) {
278+
warn('directive binding can only be added to BlockEffectScope')
279+
}
280+
281+
const directiveBindingsMap = (parentScope.dirs ||= new Map())
282+
directiveBindingsMap.set(anchor, [{ dir, instance, value, oldValue }])
283+
}

packages/runtime-vapor/src/directivesChildFragment.ts

+8-23
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { ReactiveEffect, getCurrentScope } from '@vue/reactivity'
1+
import { ReactiveEffect } from '@vue/reactivity'
22
import {
3-
type Directive,
43
type DirectiveHookName,
54
createRenderingUpdateTrigger,
65
invokeDirectiveHook,
6+
setDirectiveBinding,
77
} from './directives'
88
import { warn } from './warning'
9-
import { type BlockEffectScope, isRenderEffectScope } from './blockEffectScope'
9+
import { type BlockEffectScope, isBlockEffectScope } from './blockEffectScope'
1010
import { currentInstance } from './component'
1111
import { VaporErrorCodes, callWithErrorHandling } from './errorHandling'
1212
import { queueJob, queuePostFlushCb } from './scheduler'
@@ -25,14 +25,8 @@ export function createChildFragmentDirectives(
2525
) {
2626
let isTriggered = false
2727
const instance = currentInstance!
28-
const parentScope = getCurrentScope() as BlockEffectScope
29-
if (__DEV__) {
30-
if (!isRenderEffectScope(parentScope)) {
31-
warn('child directives can only be added to a render effect scope')
32-
}
33-
if (!instance) {
34-
warn('child directives can only be added in a component')
35-
}
28+
if (__DEV__ && !instance) {
29+
warn('child directives can only be added in a component')
3630
}
3731

3832
const callSourceWithErrorHandling = () =>
@@ -43,22 +37,13 @@ export function createChildFragmentDirectives(
4337
return
4438
}
4539

46-
const directiveBindingsMap = (parentScope.dirs ||= new Map())
47-
const dir: Directive = {
40+
setDirectiveBinding(instance, anchor, {
4841
beforeUpdate: onDirectiveBeforeUpdate,
4942
beforeMount: () => invokeChildrenDirectives('beforeMount'),
5043
mounted: () => invokeChildrenDirectives('mounted'),
5144
beforeUnmount: () => invokeChildrenDirectives('beforeUnmount'),
5245
unmounted: () => invokeChildrenDirectives('unmounted'),
53-
}
54-
directiveBindingsMap.set(anchor, [
55-
{
56-
dir,
57-
instance,
58-
value: null,
59-
oldValue: undefined,
60-
},
61-
])
46+
})
6247

6348
const effect = new ReactiveEffect(callSourceWithErrorHandling)
6449
const triggerRenderingUpdate = createRenderingUpdateTrigger(instance, effect)
@@ -93,7 +78,7 @@ export function createChildFragmentDirectives(
9378
}
9479

9580
export function invokeWithMount(scope: BlockEffectScope, handler?: () => any) {
96-
if (isRenderEffectScope(scope.parent) && !scope.parent.im) {
81+
if (isBlockEffectScope(scope.parent) && !scope.parent.im) {
9782
return handler && handler()
9883
}
9984
return invokeWithDirsHooks(scope, 'mount', handler)

0 commit comments

Comments
 (0)