|
|
@@ -1,7 +1,7 @@
|
|
|
import { extend, hasChanged } from '@vue/shared'
|
|
|
import type { ComputedRefImpl } from './computed'
|
|
|
import type { TrackOpTypes, TriggerOpTypes } from './constants'
|
|
|
-import { type Link, globalVersion, targetMap } from './dep'
|
|
|
+import { type Link, globalVersion } from './dep'
|
|
|
import { activeEffectScope } from './effectScope'
|
|
|
import { warn } from './warning'
|
|
|
|
|
|
@@ -292,7 +292,7 @@ function prepareDeps(sub: Subscriber) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-function cleanupDeps(sub: Subscriber, fromComputed = false) {
|
|
|
+function cleanupDeps(sub: Subscriber) {
|
|
|
// Cleanup unsued deps
|
|
|
let head
|
|
|
let tail = sub.depsTail
|
|
|
@@ -302,7 +302,7 @@ function cleanupDeps(sub: Subscriber, fromComputed = false) {
|
|
|
if (link.version === -1) {
|
|
|
if (link === tail) tail = prev
|
|
|
// unused - remove it from the dep's subscribing effect list
|
|
|
- removeSub(link, fromComputed)
|
|
|
+ removeSub(link)
|
|
|
// also remove it from this effect's dep list
|
|
|
removeDep(link)
|
|
|
} else {
|
|
|
@@ -394,12 +394,12 @@ export function refreshComputed(computed: ComputedRefImpl): undefined {
|
|
|
} finally {
|
|
|
activeSub = prevSub
|
|
|
shouldTrack = prevShouldTrack
|
|
|
- cleanupDeps(computed, true)
|
|
|
+ cleanupDeps(computed)
|
|
|
computed.flags &= ~EffectFlags.RUNNING
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-function removeSub(link: Link, fromComputed = false) {
|
|
|
+function removeSub(link: Link, soft = false) {
|
|
|
const { dep, prevSub, nextSub } = link
|
|
|
if (prevSub) {
|
|
|
prevSub.nextSub = nextSub
|
|
|
@@ -418,21 +418,24 @@ function removeSub(link: Link, fromComputed = false) {
|
|
|
dep.subsHead = nextSub
|
|
|
}
|
|
|
|
|
|
- if (!dep.subs) {
|
|
|
- // last subscriber removed
|
|
|
- if (dep.computed) {
|
|
|
- // if computed, unsubscribe it from all its deps so this computed and its
|
|
|
- // value can be GCed
|
|
|
- dep.computed.flags &= ~EffectFlags.TRACKING
|
|
|
- for (let l = dep.computed.deps; l; l = l.nextDep) {
|
|
|
- removeSub(l, true)
|
|
|
- }
|
|
|
- } else if (dep.map && !fromComputed) {
|
|
|
- // property dep, remove it from the owner depsMap
|
|
|
- dep.map.delete(dep.key)
|
|
|
- if (!dep.map.size) targetMap.delete(dep.target!)
|
|
|
+ if (!dep.subs && dep.computed) {
|
|
|
+ // if computed, unsubscribe it from all its deps so this computed and its
|
|
|
+ // value can be GCed
|
|
|
+ dep.computed.flags &= ~EffectFlags.TRACKING
|
|
|
+ for (let l = dep.computed.deps; l; l = l.nextDep) {
|
|
|
+ // here we are only "soft" unsubscribing because the computed still keeps
|
|
|
+ // referencing the deps and the dep should not decrease its sub count
|
|
|
+ removeSub(l, true)
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if (!soft && !--dep.sc && dep.map) {
|
|
|
+ // #11979
|
|
|
+ // property dep no longer has effect subscribers, delete it
|
|
|
+ // this mostly is for the case where an object is kept in memory but only a
|
|
|
+ // subset of its properties is tracked at one time
|
|
|
+ dep.map.delete(dep.key)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
function removeDep(link: Link) {
|