diff --git a/packages/reactivity/__tests__/effect.spec.ts b/packages/reactivity/__tests__/effect.spec.ts index 5d7a1e39cef..75b108b2da5 100644 --- a/packages/reactivity/__tests__/effect.spec.ts +++ b/packages/reactivity/__tests__/effect.spec.ts @@ -8,7 +8,12 @@ import { serializeInner, } from '@vue/runtime-test' import { ITERATE_KEY, getDepFromReactive } from '../src/dep' -import { onEffectCleanup, pauseTracking, resetTracking } from '../src/effect' +import { + onEffectCleanup, + pauseTracking, + resetTracking, + untrack, +} from '../src/effect' import { type DebuggerEvent, type ReactiveEffectRunner, @@ -1177,6 +1182,22 @@ describe('reactivity/effect', () => { expect(spy2).toHaveBeenCalledTimes(2) }) + it('should not track dependencies when using untrack', () => { + const a = ref(1) + const b = computed(() => a.value) + let dummyA + let dummyB + effect(() => { + dummyA = untrack(() => a.value) + dummyB = untrack(() => b.value) + }) + expect(dummyA).toBe(1) + expect(dummyB).toBe(1) + a.value = 2 + expect(dummyA).toBe(1) + expect(dummyB).toBe(1) + }) + describe('dep unsubscribe', () => { function getSubCount(dep: ReactiveNode | undefined) { let count = 0 diff --git a/packages/reactivity/src/effect.ts b/packages/reactivity/src/effect.ts index d48900f18cc..120cccb5dae 100644 --- a/packages/reactivity/src/effect.ts +++ b/packages/reactivity/src/effect.ts @@ -284,6 +284,16 @@ export function cleanup( } } +export function untrack(fn: () => T): T { + if (!activeSub) return fn() + const prevSub = setActiveSub() + try { + return fn() + } finally { + setActiveSub(prevSub) + } +} + /** * Registers a cleanup function for the current active effect. * The cleanup function is called right before the next effect run, or when the diff --git a/packages/reactivity/src/index.ts b/packages/reactivity/src/index.ts index ef643940b00..12a260d6f49 100644 --- a/packages/reactivity/src/index.ts +++ b/packages/reactivity/src/index.ts @@ -55,6 +55,7 @@ export { enableTracking, pauseTracking, resetTracking, + untrack, onEffectCleanup, ReactiveEffect, EffectFlags, diff --git a/packages/runtime-core/src/index.ts b/packages/runtime-core/src/index.ts index 243bde548c5..44a04f10be3 100644 --- a/packages/runtime-core/src/index.ts +++ b/packages/runtime-core/src/index.ts @@ -27,6 +27,7 @@ export { toRaw, // effect effect, + untrack, stop, getCurrentWatcher, onWatcherCleanup,