Skip to content

Commit aa828ab

Browse files
committed
Fix SSR support [skip ci]
1 parent aa81b75 commit aa828ab

File tree

1 file changed

+36
-9
lines changed

1 file changed

+36
-9
lines changed

packages/reactivity/src/computed.ts

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,16 @@ export interface WritableComputedOptions<T, S = T> {
4040
set: ComputedSetter<S>
4141
}
4242

43+
let globalVersion = 0
44+
let initSSR = false
45+
4346
/**
4447
* @private exported by @vue/reactivity for Vue core use, but not exported from
4548
* the main vue package
4649
*/
4750
export class ComputedRefImpl<T = any> implements IComputed {
4851
_value: T | undefined = undefined
52+
version = -1
4953

5054
// Dependency
5155
subs: Link | undefined = undefined
@@ -72,6 +76,10 @@ export class ComputedRefImpl<T = any> implements IComputed {
7276
get effect(): this {
7377
return this
7478
}
79+
// for backwards compat
80+
get dep(): Dependency {
81+
return this
82+
}
7583
// dev only
7684
onTrack?: (event: DebuggerEvent) => void
7785
// dev only
@@ -95,17 +103,36 @@ export class ComputedRefImpl<T = any> implements IComputed {
95103
}
96104

97105
get value(): T {
98-
const dirtyLevel = this.dirtyLevel
99-
if (dirtyLevel === (2 satisfies DirtyLevels.MaybeDirty)) {
100-
Subscriber.resolveMaybeDirty(this)
101-
if (this.dirtyLevel === (3 satisfies DirtyLevels.Dirty)) {
106+
// In SSR there will be no render effect, so the computed has no subscriber
107+
// and therefore tracks no deps, thus we cannot rely on the dirty check.
108+
// Instead, computed always re-evaluate and relies on the globalVersion
109+
// fast path above for caching.
110+
if (this.isSSR) {
111+
if (!initSSR) {
112+
initSSR = true
113+
const propagate = Dependency.propagate
114+
Dependency.propagate = (link: Link) => {
115+
globalVersion++
116+
propagate(link)
117+
}
118+
}
119+
if (globalVersion !== this.version) {
120+
this.version = globalVersion
121+
this.update()
122+
}
123+
} else {
124+
const dirtyLevel = this.dirtyLevel
125+
if (dirtyLevel === (2 satisfies DirtyLevels.MaybeDirty)) {
126+
Subscriber.resolveMaybeDirty(this)
127+
if (this.dirtyLevel === (3 satisfies DirtyLevels.Dirty)) {
128+
this.update()
129+
}
130+
} else if (
131+
dirtyLevel === (3 satisfies DirtyLevels.Dirty) ||
132+
dirtyLevel === (4 satisfies DirtyLevels.Released)
133+
) {
102134
this.update()
103135
}
104-
} else if (
105-
dirtyLevel === (3 satisfies DirtyLevels.Dirty) ||
106-
dirtyLevel === (4 satisfies DirtyLevels.Released)
107-
) {
108-
this.update()
109136
}
110137
const activeTrackId = System.activeTrackId
111138
if (activeTrackId !== 0 && this.subsTail?.trackId !== activeTrackId) {

0 commit comments

Comments
 (0)