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

View File

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

View File

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

View File

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

View File

@ -98,13 +98,6 @@ const DEFAULT_HANDLE_ERROR: HandleError = (err: unknown) => {
const cleanupMap: WeakMap<ReactiveEffect, (() => void)[]> = new WeakMap() const cleanupMap: WeakMap<ReactiveEffect, (() => void)[]> = new WeakMap()
let activeEffect: ReactiveEffect | undefined = undefined 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 * Registers a cleanup callback on the current active effect. This
* registered cleanup callback will be invoked right before the * registered cleanup callback will be invoked right before the

View File

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

View File

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

View File

@ -1,5 +1,4 @@
import { import {
getCurrentEffect,
getCurrentScope, getCurrentScope,
onEffectCleanup, onEffectCleanup,
onScopeDispose, onScopeDispose,
@ -27,25 +26,19 @@ export function on(
el: HTMLElement, el: HTMLElement,
event: string, event: string,
handlerGetter: () => undefined | ((...args: any[]) => any), handlerGetter: () => undefined | ((...args: any[]) => any),
options: AddEventListenerOptions & ModifierOptions = {}, options: AddEventListenerOptions &
ModifierOptions & { effect?: boolean } = {},
) { ) {
const handler: DelegatedHandler = eventHandler(handlerGetter, options) const handler: DelegatedHandler = eventHandler(handlerGetter, options)
const cleanupMetadata = recordEventMetadata(el, event, handler) const cleanupMetadata = recordEventMetadata(el, event, handler)
let cleanupEvent: (() => void) | undefined let cleanupEvent: (() => void) | undefined
queuePostRenderEffect(() => { queuePostRenderEffect(() => {
cleanupEvent = addEventListener(el, event, handler, options) cleanupEvent = addEventListener(el, event, handler, options)
}) })
const scope = getCurrentScope() if (options.effect) {
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) {
onEffectCleanup(cleanup) onEffectCleanup(cleanup)
} else if (scope) { } else if (getCurrentScope()) {
onScopeDispose(cleanup) onScopeDispose(cleanup)
} }

View File

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