]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
perf(reactivity): better computed tracking (#710)
authorjods <jods4@users.noreply.github.com>
Sun, 9 Feb 2020 20:25:17 +0000 (21:25 +0100)
committerGitHub <noreply@github.com>
Sun, 9 Feb 2020 20:25:17 +0000 (15:25 -0500)
packages/reactivity/src/computed.ts

index 1f1d8ea43d7f76649f7aa941cd7ce8be4deac24c..c3c2a3ad94ef28cd5bdccfd5bb80dcffbbcbbf7e 100644 (file)
@@ -1,4 +1,5 @@
-import { effect, ReactiveEffect, activeEffect } from './effect'
+import { effect, ReactiveEffect, trigger, track } from './effect'
+import { TriggerOpTypes, TrackOpTypes } from './operations'
 import { Ref, UnwrapRef } from './ref'
 import { isFunction, NOOP } from '@vue/shared'
 
@@ -42,16 +43,20 @@ export function computed<T>(
 
   let dirty = true
   let value: T
+  let computed: ComputedRef<T>
 
   const runner = effect(getter, {
     lazy: true,
     // mark effect as computed so that it gets priority during trigger
     computed: true,
     scheduler: () => {
-      dirty = true
+      if (!dirty) {
+        dirty = true
+        trigger(computed, TriggerOpTypes.SET, 'value')
+      }
     }
   })
-  return {
+  computed = {
     _isRef: true,
     // expose effect so computed can be stopped
     effect: runner,
@@ -60,27 +65,12 @@ export function computed<T>(
         value = runner()
         dirty = false
       }
-      // When computed effects are accessed in a parent effect, the parent
-      // should track all the dependencies the computed property has tracked.
-      // This should also apply for chained computed properties.
-      trackChildRun(runner)
+      track(computed, TrackOpTypes.GET, 'value')
       return value
     },
     set value(newValue: T) {
       setter(newValue)
     }
   } as any
-}
-
-function trackChildRun(childRunner: ReactiveEffect) {
-  if (activeEffect === undefined) {
-    return
-  }
-  for (let i = 0; i < childRunner.deps.length; i++) {
-    const dep = childRunner.deps[i]
-    if (!dep.has(activeEffect)) {
-      dep.add(activeEffect)
-      activeEffect.deps.push(dep)
-    }
-  }
+  return computed
 }