]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(reactivity): avoid cross-component dependency leaks in setup()
authorEvan You <yyx990803@gmail.com>
Tue, 18 Feb 2020 04:14:07 +0000 (23:14 -0500)
committerEvan You <yyx990803@gmail.com>
Tue, 18 Feb 2020 04:14:07 +0000 (23:14 -0500)
packages/reactivity/src/effect.ts
packages/reactivity/src/index.ts
packages/runtime-core/src/apiLifecycle.ts
packages/runtime-core/src/component.ts
packages/runtime-core/src/warning.ts

index 46969d3c33cc238c5f98f369dc9248cf319c0ff0..bffcc8024bc6c7b09d9fe2ac7f97b67902bb71bf 100644 (file)
@@ -95,11 +95,13 @@ function run(effect: ReactiveEffect, fn: Function, args: unknown[]): unknown {
   if (!effectStack.includes(effect)) {
     cleanup(effect)
     try {
+      enableTracking()
       effectStack.push(effect)
       activeEffect = effect
       return fn(...args)
     } finally {
       effectStack.pop()
+      resetTracking()
       activeEffect = effectStack[effectStack.length - 1]
     }
   }
@@ -116,15 +118,23 @@ function cleanup(effect: ReactiveEffect) {
 }
 
 let shouldTrack = true
+const trackStack: boolean[] = []
 
 export function pauseTracking() {
+  trackStack.push(shouldTrack)
   shouldTrack = false
 }
 
-export function resumeTracking() {
+export function enableTracking() {
+  trackStack.push(shouldTrack)
   shouldTrack = true
 }
 
+export function resetTracking() {
+  const last = trackStack.pop()
+  shouldTrack = last === undefined ? true : last
+}
+
 export function track(target: object, type: TrackOpTypes, key: unknown) {
   if (!shouldTrack || activeEffect === undefined) {
     return
index 80e9e622703ba9dcbb01ccc30b1475e3995b548d..040dd8c673df873f61da600ea6a25d7bed4e5b73 100644 (file)
@@ -21,8 +21,11 @@ export {
 export {
   effect,
   stop,
+  trigger,
+  track,
+  enableTracking,
   pauseTracking,
-  resumeTracking,
+  resetTracking,
   ITERATE_KEY,
   ReactiveEffect,
   ReactiveEffectOptions,
index 8733ecd2bde039e9a8db2a32326247c04c7aa593..4ee86b60c218a7a99c9272f313731578221ea171 100644 (file)
@@ -9,7 +9,7 @@ import { ComponentPublicInstance } from './componentProxy'
 import { callWithAsyncErrorHandling, ErrorTypeStrings } from './errorHandling'
 import { warn } from './warning'
 import { capitalize } from '@vue/shared'
-import { pauseTracking, resumeTracking, DebuggerEvent } from '@vue/reactivity'
+import { pauseTracking, resetTracking, DebuggerEvent } from '@vue/reactivity'
 
 export { onActivated, onDeactivated } from './components/KeepAlive'
 
@@ -39,7 +39,7 @@ export function injectHook(
         setCurrentInstance(target)
         const res = callWithAsyncErrorHandling(hook, target, type, args)
         setCurrentInstance(null)
-        resumeTracking()
+        resetTracking()
         return res
       })
     if (prepend) {
index d90249a9823294e87236efa7a02a372dcb5e24cb..dc7d3a24c562a3cc8d0a01f045d0cfde13a8b262 100644 (file)
@@ -1,5 +1,10 @@
 import { VNode, VNodeChild, isVNode } from './vnode'
-import { ReactiveEffect, shallowReadonly } from '@vue/reactivity'
+import {
+  ReactiveEffect,
+  shallowReadonly,
+  pauseTracking,
+  resetTracking
+} from '@vue/reactivity'
 import {
   PublicInstanceProxyHandlers,
   ComponentPublicInstance,
@@ -341,12 +346,14 @@ function setupStatefulComponent(
 
     currentInstance = instance
     currentSuspense = parentSuspense
+    pauseTracking()
     const setupResult = callWithErrorHandling(
       setup,
       instance,
       ErrorCodes.SETUP_FUNCTION,
       [propsProxy, setupContext]
     )
+    resetTracking()
     currentInstance = null
     currentSuspense = null
 
index 083bda553e03ff011589d31544ee623e580d16d0..ef6168d242b04f3715675da2e40818f34e43963f 100644 (file)
@@ -1,7 +1,7 @@
 import { VNode } from './vnode'
 import { Data, ComponentInternalInstance, Component } from './component'
 import { isString, isFunction } from '@vue/shared'
-import { toRaw, isRef, pauseTracking, resumeTracking } from '@vue/reactivity'
+import { toRaw, isRef, pauseTracking, resetTracking } from '@vue/reactivity'
 import { callWithErrorHandling, ErrorCodes } from './errorHandling'
 
 type ComponentVNode = VNode & {
@@ -60,7 +60,7 @@ export function warn(msg: string, ...args: any[]) {
     console.warn(...warnArgs)
   }
 
-  resumeTracking()
+  resetTracking()
 }
 
 function getComponentTrace(): ComponentTraceStack {