refactor: remove getCurrentEffect, add effect flag for on

Use the effect flag to distinguish whether it is in the effect of a v-for block.
This commit is contained in:
三咲智子 Kevin Deng 2024-03-07 17:40:51 +08:00
parent 03d1d0a956
commit 280b8cbdab
No known key found for this signature in database
GPG Key ID: 69992F2250DFD93E
9 changed files with 32 additions and 29 deletions

View File

@ -18,7 +18,11 @@ const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_renderEffect(() => _on(n0, _ctx.event, () => _ctx.handler))
_renderEffect(() => {
_on(n0, _ctx.event, () => _ctx.handler, {
effect: true
})
})
return n0
}"
`;
@ -29,7 +33,11 @@ const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_renderEffect(() => _on(n0, _ctx.event(_ctx.foo), () => _ctx.handler))
_renderEffect(() => {
_on(n0, _ctx.event(_ctx.foo), () => _ctx.handler, {
effect: true
})
})
return n0
}"
`;
@ -40,7 +48,11 @@ const t0 = _template("<div></div>")
export function render(_ctx) {
const n0 = t0()
_renderEffect(() => _on(n0, _ctx.event, () => _ctx.handler))
_renderEffect(() => {
_on(n0, _ctx.event, () => _ctx.handler, {
effect: true
})
})
return n0
}"
`;
@ -366,7 +378,8 @@ export function render(_ctx) {
const n0 = t0()
_renderEffect(() => {
_on(n0, (_ctx.event) === "click" ? "mouseup" : (_ctx.event), () => _ctx.test, {
modifiers: ["middle"]
modifiers: ["middle"],
effect: true
})
})
return n0
@ -396,7 +409,8 @@ export function render(_ctx) {
_renderEffect(() => {
_on(n0, (_ctx.event) === "click" ? "contextmenu" : (_ctx.event), () => _ctx.test, {
modifiers: ["right"],
keys: ["right"]
keys: ["right"],
effect: true
})
})
return n0
@ -424,7 +438,8 @@ export function render(_ctx) {
_renderEffect(() => {
_on(n0, _ctx.e, () => _ctx.test, {
modifiers: ["left"],
keys: ["left"]
keys: ["left"],
effect: true
})
})
return n0

View File

@ -16,7 +16,7 @@ export function genSetEvent(
context: CodegenContext,
): CodeFragment[] {
const { vaporHelper, options } = context
const { element, key, keyOverride, value, modifiers, delegate } = oper
const { element, key, keyOverride, value, modifiers, delegate, effect } = oper
const name = genName()
const handler = genEventHandler()
@ -77,7 +77,7 @@ export function genSetEvent(
function genEventOptions(): CodeFragment[] | undefined {
let { options, keys, nonKeys } = modifiers
if (!options.length && !nonKeys.length && !keys.length) return
if (!options.length && !nonKeys.length && !keys.length && !effect) return
return genMulti(
[
@ -87,6 +87,7 @@ export function genSetEvent(
],
!!nonKeys.length && ['modifiers: ', genArrayExpression(nonKeys)],
!!keys.length && ['keys: ', genArrayExpression(keys)],
effect && ['effect: true'],
...options.map((option): CodeFragment[] => [`${option}: true`]),
)
}

View File

@ -116,6 +116,8 @@ export interface SetEventIRNode extends BaseIRNode {
}
keyOverride?: KeyOverride
delegate: boolean
/** Whether it's in effect */
effect: boolean
}
export interface SetHtmlIRNode extends BaseIRNode {

View File

@ -70,6 +70,7 @@ export const transformVOn: DirectiveTransform = (dir, node, context) => {
},
keyOverride,
delegate,
effect: !arg.isStatic,
}
context.registerEffect([arg], [operation])

View File

@ -98,13 +98,6 @@ const DEFAULT_HANDLE_ERROR: HandleError = (err: unknown) => {
const cleanupMap: WeakMap<ReactiveEffect, (() => void)[]> = new WeakMap()
let activeEffect: ReactiveEffect | undefined = undefined
/**
* Returns the current active effect if there is one.
*/
export function getCurrentEffect() {
return activeEffect
}
/**
* Registers a cleanup callback on the current active effect. This
* registered cleanup callback will be invoked right before the

View File

@ -70,7 +70,7 @@ export class ReactiveEffect<T = any> {
public fn: () => T,
public trigger: () => void,
public scheduler?: EffectScheduler,
public scope?: EffectScope,
scope?: EffectScope,
) {
recordEffectScope(this, scope)
}

View File

@ -72,7 +72,6 @@ export {
export { TrackOpTypes, TriggerOpTypes, ReactiveFlags } from './constants'
export {
baseWatch,
getCurrentEffect,
onEffectCleanup,
traverse,
BaseWatchErrorCodes,

View File

@ -1,5 +1,4 @@
import {
getCurrentEffect,
getCurrentScope,
onEffectCleanup,
onScopeDispose,
@ -27,25 +26,19 @@ export function on(
el: HTMLElement,
event: string,
handlerGetter: () => undefined | ((...args: any[]) => any),
options: AddEventListenerOptions & ModifierOptions = {},
options: AddEventListenerOptions &
ModifierOptions & { effect?: boolean } = {},
) {
const handler: DelegatedHandler = eventHandler(handlerGetter, options)
const cleanupMetadata = recordEventMetadata(el, event, handler)
let cleanupEvent: (() => void) | undefined
queuePostRenderEffect(() => {
cleanupEvent = addEventListener(el, event, handler, options)
})
const scope = getCurrentScope()
const effect = getCurrentEffect()
// If we are in an effect and the effect has the same scope as
// the current scope, we can cleanup when the effect is disposed
// This solves the issue where createFor itself has an effect,
// but this effect is unrelated to its block.
if (effect && effect.scope === scope) {
if (options.effect) {
onEffectCleanup(cleanup)
} else if (scope) {
} else if (getCurrentScope()) {
onScopeDispose(cleanup)
}

View File

@ -29,7 +29,6 @@ export {
// effect
stop,
ReactiveEffect,
getCurrentEffect,
onEffectCleanup,
// effect scope
effectScope,