From ccd3f3f5c6517ad2f5622390736f20e230ed0009 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 3 Dec 2024 23:26:30 +0800 Subject: [PATCH] refactor(reactivity): only setup onTrigger debug flags on assign --- packages/reactivity/src/computed.ts | 9 +++++---- packages/reactivity/src/debug.ts | 16 ++++++++++++++-- packages/reactivity/src/effect.ts | 9 +++++---- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/packages/reactivity/src/computed.ts b/packages/reactivity/src/computed.ts index 12f2b249a..15748c88e 100644 --- a/packages/reactivity/src/computed.ts +++ b/packages/reactivity/src/computed.ts @@ -1,6 +1,6 @@ import { hasChanged, isFunction } from '@vue/shared' import { ReactiveFlags, TrackOpTypes } from './constants' -import { onTrack, setupFlagsHandler } from './debug' +import { onTrack, setupOnTrigger } from './debug' import { type DebuggerEvent, type DebuggerOptions, @@ -130,9 +130,6 @@ export class ComputedRefImpl implements IComputed { private readonly setter: ComputedSetter | undefined, ) { this[ReactiveFlags.IS_READONLY] = !setter - if (__DEV__) { - setupFlagsHandler(this) - } } get value(): T { @@ -188,6 +185,10 @@ export class ComputedRefImpl implements IComputed { } } +if (__DEV__) { + setupOnTrigger(ComputedRefImpl) +} + /** * Takes a getter function and returns a readonly reactive ref object for the * returned value from the getter. It can also take an object with get and set diff --git a/packages/reactivity/src/debug.ts b/packages/reactivity/src/debug.ts index 41908a0d1..14d22f0a1 100644 --- a/packages/reactivity/src/debug.ts +++ b/packages/reactivity/src/debug.ts @@ -44,12 +44,24 @@ export function onTrigger(sub: Link['sub']): void { } } -export function setupFlagsHandler(target: Subscriber): void { +export function setupOnTrigger(target: { new (...args: any[]): any }): void { if (!__DEV__) { throw new Error( - `Internal error: setupFlagsHandler should be called only in development.`, + `Internal error: setupOnTrigger should be called only in development.`, ) } + Object.defineProperty(target.prototype, 'onTrigger', { + get() { + return this._onTrigger + }, + set(val) { + if (!this._onTrigger) setupFlagsHandler(this) + this._onTrigger = val + }, + }) +} + +function setupFlagsHandler(target: Subscriber): void { // @ts-expect-error target._flags = target.flags Object.defineProperty(target, 'flags', { diff --git a/packages/reactivity/src/effect.ts b/packages/reactivity/src/effect.ts index d0aa92b33..690483caa 100644 --- a/packages/reactivity/src/effect.ts +++ b/packages/reactivity/src/effect.ts @@ -1,6 +1,6 @@ import { extend } from '@vue/shared' import type { TrackOpTypes, TriggerOpTypes } from './constants' -import { setupFlagsHandler } from './debug' +import { setupOnTrigger } from './debug' import { activeEffectScope } from './effectScope' import { type IEffect, @@ -74,9 +74,6 @@ export class ReactiveEffect implements IEffect, ReactiveEffectOptions { if (activeEffectScope && activeEffectScope.active) { activeEffectScope.effects.push(this) } - if (__DEV__) { - setupFlagsHandler(this) - } } get active(): boolean { @@ -176,6 +173,10 @@ export class ReactiveEffect implements IEffect, ReactiveEffectOptions { } } +if (__DEV__) { + setupOnTrigger(ReactiveEffect) +} + export interface ReactiveEffectRunner { (): T effect: ReactiveEffect