Skip to content

Commit

Permalink
refactor: organize code
Browse files Browse the repository at this point in the history
  • Loading branch information
LittleSound committed Apr 9, 2024
1 parent e760d68 commit 17e46d4
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 92 deletions.
17 changes: 7 additions & 10 deletions packages/runtime-vapor/src/apiCreateFor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@ import { type Block, type Fragment, fragmentKey } from './apiRender'
import { warn } from './warning'
import { currentInstance } from './component'
import { componentKey } from './component'
import { RenderEffectScope, isRenderEffectScope } from './renderEffectScope'
import {
RenderEffectScope,
createChildFragmentDirectives,
invokeWithMount,
invokeWithUnmount,
invokeWithUpdate,
isRenderEffectScope,
} from './renderEffectScope'
import { createChildFragmentDirectives } from './createChildFragmentDirectives'
} from './directivesChildFragment'

interface ForBlock extends Fragment {
scope: RenderEffectScope
Expand All @@ -43,17 +42,16 @@ export const createFor = (
let newBlocks: ForBlock[]
let parent: ParentNode | undefined | null
const update = getMemo ? updateWithMemo : updateWithoutMemo
const parentScope = getCurrentScope()
const parentScope = getCurrentScope()!
const parentAnchor = __DEV__ ? createComment('for') : createTextNode()
const ref: Fragment = {
nodes: oldBlocks,
[fragmentKey]: true,
}

const instance = currentInstance!
if (!instance || !isRenderEffectScope(parentScope)) {
if (__DEV__) warn('createFor() can only be used inside setup()')
return ref
if (__DEV__ && (!instance || !isRenderEffectScope(parentScope))) {
warn('createFor() can only be used inside setup()')
}

createChildFragmentDirectives(
Expand All @@ -74,8 +72,7 @@ export const createFor = (
idx: number,
anchor: Node = parentAnchor,
): ForBlock {
const scope = new RenderEffectScope(instance)
scope.parent = parentScope
const scope = new RenderEffectScope(instance, parentScope)

const [item, key, index] = getItem(source, idx)
const block: ForBlock = (newBlocks[idx] = {
Expand Down
15 changes: 7 additions & 8 deletions packages/runtime-vapor/src/apiCreateIf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { getCurrentScope } from '@vue/reactivity'
import { createComment, createTextNode, insert, remove } from './dom/element'
import { currentInstance } from './component'
import { warn } from './warning'
import { RenderEffectScope, isRenderEffectScope } from './renderEffectScope'
import {
RenderEffectScope,
createChildFragmentDirectives,
invokeWithMount,
invokeWithUnmount,
invokeWithUpdate,
} from './renderEffectScope'
import { createChildFragmentDirectives } from './createChildFragmentDirectives'
} from './directivesChildFragment'

type BlockFn = () => Block

Expand All @@ -26,7 +26,7 @@ export const createIf = (
let parent: ParentNode | undefined | null
let block: Block | undefined
let scope: RenderEffectScope | undefined
const parentScope = getCurrentScope()
const parentScope = getCurrentScope()!
const anchor = __DEV__ ? createComment('if') : createTextNode()
const fragment: Fragment = {
nodes: [],
Expand All @@ -35,8 +35,8 @@ export const createIf = (
}

const instance = currentInstance!
if (__DEV__) {
if (!instance) warn('createIf() can only be used inside setup()')
if (__DEV__ && (!instance || !isRenderEffectScope(parentScope))) {
warn('createIf() can only be used inside setup()')
}

// TODO: SSR
Expand Down Expand Up @@ -78,8 +78,7 @@ export const createIf = (
invokeWithUnmount(scope!, () => remove(block!, parent!))
}
if ((branch = (oldValue = newValue) ? b1 : b2)) {
scope = new RenderEffectScope(instance)
scope.parent = parentScope
scope = new RenderEffectScope(instance, parentScope)
fragment.nodes = block = scope.run(branch)!
invokeWithMount(scope, () => parent && insert(block!, parent, anchor))
} else {
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime-vapor/src/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ export function createComponentInstance(
*/
// [VaporLifecycleHooks.SERVER_PREFETCH]: null,
}
instance.scope = new RenderEffectScope(instance, true /* detached */)
instance.scope = new RenderEffectScope(instance, parent ? parent.scope : null)
initProps(instance, rawProps, !isFunction(component))
initSlots(instance, slots, dynamicSlots)
instance.emit = emit.bind(null, instance)
Expand Down
1 change: 0 additions & 1 deletion packages/runtime-vapor/src/componentLifecycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export function invokeLifecycle(

function invokeCurrent() {
const hooks = instance[lifecycle]

if (hooks) {
const fn = () => {
const reset = setCurrentInstance(instance)
Expand Down
10 changes: 5 additions & 5 deletions packages/runtime-vapor/src/directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ export function withDirectives<T extends Node>(
directives: DirectiveArguments,
): T {
let bindings: DirectiveBinding[]
const instance = currentInstance
const parentScope = getCurrentScope()
const instance = currentInstance!
const parentScope = getCurrentScope() as RenderEffectScope

if (!instance || !isRenderEffectScope(parentScope)) {
if (__DEV__) warn(`withDirectives() can only be used inside setup()`)
return node
if (__DEV__) {
if (!instance || !isRenderEffectScope(parentScope))
warn(`withDirectives() can only be used inside setup()`)
}

const directivesMap = (parentScope.dirs ||= new Map())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ import {
import { warn } from './warning'
import {
type RenderEffectScope,
invokeWithUpdate,
isRenderEffectScope,
} from './renderEffectScope'
import { currentInstance } from './component'
import { VaporErrorCodes, callWithErrorHandling } from './errorHandling'
import { queueJob } from './scheduler'
import { queueJob, queuePostRenderEffect } from './scheduler'

export function createChildFragmentDirectives(
anchor: Node,
Expand Down Expand Up @@ -84,3 +83,62 @@ export function createChildFragmentDirectives(
}
}
}

export function invokeWithMount(scope: RenderEffectScope, handler?: () => any) {
if (isRenderEffectScope(scope.parent) && !scope.parent.im) {
return handler && handler()
}
return invokeWithDirsHooks(scope, 'mount', handler)
}

export function invokeWithUnmount(
scope: RenderEffectScope,
handler?: () => void,
) {
try {
return invokeWithDirsHooks(scope, 'unmount', handler)
} finally {
scope.stop()
}
}

export function invokeWithUpdate(
scope: RenderEffectScope,
handler?: () => void,
) {
return invokeWithDirsHooks(scope, 'update', handler)
}

const lifecycleMap = {
mount: ['beforeMount', 'mounted'],
update: ['beforeUpdate', 'updated'],
unmount: ['beforeUnmount', 'unmounted'],
} as const

function invokeWithDirsHooks(
scope: RenderEffectScope,
name: keyof typeof lifecycleMap,
handler?: () => any,
) {
const { dirs, ie: instance } = scope
const [before, after] = lifecycleMap[name]

if (!dirs) {
const res = handler && handler()
if (name === 'mount') {
queuePostRenderEffect(() => (scope.im = true))
}
return res
}

invokeDirectiveHook(instance, before, scope)
try {
if (handler) {
return handler()
}
} finally {
queuePostRenderEffect(() => {
invokeDirectiveHook(instance, after, scope)
})
}
}
2 changes: 1 addition & 1 deletion packages/runtime-vapor/src/renderEffect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,6 @@ export function renderEffect(cb: () => void) {
effect.run()
}

reset?.()
reset && reset()
}
}
74 changes: 10 additions & 64 deletions packages/runtime-vapor/src/renderEffectScope.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { EffectScope } from '@vue/reactivity'
import { EffectScope, getCurrentScope } from '@vue/reactivity'
import type { ComponentInternalInstance } from './component'
import { type DirectiveBindingsMap, invokeDirectiveHook } from './directives'
import { queuePostRenderEffect } from './scheduler'
import type { DirectiveBindingsMap } from './directives'

export class RenderEffectScope extends EffectScope {
/**
Expand All @@ -22,9 +21,15 @@ export class RenderEffectScope extends EffectScope {

constructor(
instance: ComponentInternalInstance,
public detached = false,
parentScope: EffectScope | null,
) {
super(detached)
const isInOtherScope = parentScope && parentScope !== getCurrentScope()
isInOtherScope && parentScope.on()
try {
super(!parentScope)
} finally {
isInOtherScope && parentScope.off()
}
this.im = false
this.ie = instance
}
Expand All @@ -35,62 +40,3 @@ export function isRenderEffectScope(
): scope is RenderEffectScope {
return scope instanceof RenderEffectScope
}

export function invokeWithMount(scope: RenderEffectScope, handler?: () => any) {
if (isRenderEffectScope(scope.parent) && !scope.parent.im) {
return handler && handler()
}
return invokeWithDirsHooks(scope, 'mount', handler)
}

export function invokeWithUnmount(
scope: RenderEffectScope,
handler?: () => void,
) {
try {
return invokeWithDirsHooks(scope, 'unmount', handler)
} finally {
scope.stop()
}
}

export function invokeWithUpdate(
scope: RenderEffectScope,
handler?: () => void,
) {
return invokeWithDirsHooks(scope, 'update', handler)
}

const lifecycleMap = {
mount: ['beforeMount', 'mounted'],
update: ['beforeUpdate', 'updated'],
unmount: ['beforeUnmount', 'unmounted'],
} as const

function invokeWithDirsHooks(
scope: RenderEffectScope,
name: keyof typeof lifecycleMap,
handler?: () => any,
) {
const { dirs, ie: instance } = scope
const [before, after] = lifecycleMap[name]

if (!dirs) {
const res = handler && handler()
if (name === 'mount') {
queuePostRenderEffect(() => (scope.im = true))
}
return res
}

invokeDirectiveHook(instance, before, scope)
try {
if (handler) {
return handler()
}
} finally {
queuePostRenderEffect(() => {
invokeDirectiveHook(instance, after, scope)
})
}
}

0 comments on commit 17e46d4

Please sign in to comment.