Skip to content

Commit 3710635

Browse files
committed
Try fix vuejs#10236
1 parent 65eedb1 commit 3710635

File tree

10 files changed

+33
-87
lines changed

10 files changed

+33
-87
lines changed

packages/reactivity/__tests__/computed.spec.ts

-21
Original file line numberDiff line numberDiff line change
@@ -122,21 +122,6 @@ describe('reactivity/computed', () => {
122122
expect(getter2).toHaveBeenCalledTimes(2)
123123
})
124124

125-
it('should no longer update when stopped', () => {
126-
const value = reactive<{ foo?: number }>({})
127-
const cValue = computed(() => value.foo)
128-
let dummy
129-
effect(() => {
130-
dummy = cValue.value
131-
})
132-
expect(dummy).toBe(undefined)
133-
value.foo = 1
134-
expect(dummy).toBe(1)
135-
cValue.effect.stop()
136-
value.foo = 2
137-
expect(dummy).toBe(1)
138-
})
139-
140125
it('should support setter', () => {
141126
const n = ref(1)
142127
const plusOne = computed({
@@ -218,12 +203,6 @@ describe('reactivity/computed', () => {
218203
expect(isReadonly(z.value.a)).toBe(false)
219204
})
220205

221-
it('should expose value when stopped', () => {
222-
const x = computed(() => 1)
223-
x.effect.stop()
224-
expect(x.value).toBe(1)
225-
})
226-
227206
it('debug: onTrack', () => {
228207
let events: DebuggerEvent[] = []
229208
const onTrack = vi.fn((e: DebuggerEvent) => {

packages/reactivity/__tests__/deferredComputed.spec.ts

-16
Original file line numberDiff line numberDiff line change
@@ -136,20 +136,4 @@ describe('deferred computed', () => {
136136
c2.value
137137
expect(effectSpy).toHaveBeenCalledTimes(2)
138138
})
139-
140-
test('should not compute if deactivated before scheduler is called', () => {
141-
const c1Spy = vi.fn()
142-
const src = ref(0)
143-
const c1 = computed(() => {
144-
c1Spy()
145-
return src.value % 2
146-
})
147-
effect(() => c1.value)
148-
expect(c1Spy).toHaveBeenCalledTimes(1)
149-
150-
c1.effect.stop()
151-
// trigger
152-
src.value++
153-
expect(c1Spy).toHaveBeenCalledTimes(1)
154-
})
155139
})

packages/reactivity/__tests__/effectScope.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,8 @@ describe('reactivity/effect/scope', () => {
267267
r.value++
268268
c!.value
269269
await nextTick()
270+
expect(computedSpy).toHaveBeenCalledTimes(3)
270271
// should not trigger anymore
271-
expect(computedSpy).toHaveBeenCalledTimes(2)
272272
expect(watchSpy).toHaveBeenCalledTimes(1)
273273
expect(watchEffectSpy).toHaveBeenCalledTimes(2)
274274
})

packages/reactivity/src/computed.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ export class ComputedRefImpl<T> {
5252
),
5353
)
5454
this.effect.computed = this
55-
this.effect.active = this._cacheable = !isSSR
55+
// TODO: How SSR affect computed?
56+
// this.effect.active = this._cacheable = !isSSR
57+
this._cacheable = !isSSR
5658
this[ReactiveFlags.IS_READONLY] = isReadonly
5759
}
5860

packages/reactivity/src/effect.ts

+15-7
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ export type DebuggerEventExtraInfo = {
2626
export let activeEffect: ReactiveEffect | undefined
2727

2828
export class ReactiveEffect<T = any> {
29-
active = true
3029
deps: Dep[] = []
3130

3231
/**
@@ -39,7 +38,6 @@ export class ReactiveEffect<T = any> {
3938
*/
4039
allowRecurse?: boolean
4140

42-
onStop?: () => void
4341
// dev only
4442
onTrack?: (event: DebuggerEvent) => void
4543
// dev only
@@ -105,9 +103,6 @@ export class ReactiveEffect<T = any> {
105103

106104
run() {
107105
this._dirtyLevel = DirtyLevels.NotDirty
108-
if (!this.active) {
109-
return this.fn()
110-
}
111106
let lastShouldTrack = shouldTrack
112107
let lastEffect = activeEffect
113108
try {
@@ -123,6 +118,19 @@ export class ReactiveEffect<T = any> {
123118
shouldTrack = lastShouldTrack
124119
}
125120
}
121+
}
122+
123+
export class ReactiveSideEffect<T = any> extends ReactiveEffect<T> {
124+
active = true
125+
126+
onStop?: () => void
127+
128+
run() {
129+
if (!this.active) {
130+
return this.fn()
131+
}
132+
return super.run()
133+
}
126134

127135
stop() {
128136
if (this.active) {
@@ -177,7 +185,7 @@ export interface ReactiveEffectOptions extends DebuggerOptions {
177185

178186
export interface ReactiveEffectRunner<T = any> {
179187
(): T
180-
effect: ReactiveEffect
188+
effect: ReactiveSideEffect
181189
}
182190

183191
/**
@@ -198,7 +206,7 @@ export function effect<T = any>(
198206
fn = (fn as ReactiveEffectRunner).effect.fn
199207
}
200208

201-
const _effect = new ReactiveEffect(fn, NOOP, () => {
209+
const _effect = new ReactiveSideEffect(fn, NOOP, () => {
202210
if (_effect.dirty) {
203211
_effect.run()
204212
}

packages/reactivity/src/effectScope.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ReactiveEffect } from './effect'
1+
import type { ReactiveEffect, ReactiveSideEffect } from './effect'
22
import { warn } from './warning'
33

44
let activeEffectScope: EffectScope | undefined
@@ -11,7 +11,7 @@ export class EffectScope {
1111
/**
1212
* @internal
1313
*/
14-
effects: ReactiveEffect[] = []
14+
effects: (ReactiveEffect | ReactiveSideEffect)[] = []
1515
/**
1616
* @internal
1717
*/
@@ -82,7 +82,10 @@ export class EffectScope {
8282
if (this._active) {
8383
let i, l
8484
for (i = 0, l = this.effects.length; i < l; i++) {
85-
this.effects[i].stop()
85+
const effect = this.effects[i]
86+
if ('stop' in effect) {
87+
effect.stop()
88+
}
8689
}
8790
for (i = 0, l = this.cleanups.length; i < l; i++) {
8891
this.cleanups[i]()

packages/reactivity/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export {
5454
pauseScheduling,
5555
resetScheduling,
5656
ReactiveEffect,
57+
ReactiveSideEffect,
5758
type ReactiveEffectRunner,
5859
type ReactiveEffectOptions,
5960
type EffectScheduler,

packages/runtime-core/__tests__/apiSetupHelpers.spec.ts

-35
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import {
22
type ComponentInternalInstance,
3-
type ComputedRef,
43
type SetupContext,
54
Suspense,
6-
computed,
75
createApp,
86
defineComponent,
97
getCurrentInstance,
@@ -419,38 +417,5 @@ describe('SFC <script setup> helpers', () => {
419417
expect(uids.one.before).toBe(uids.one.after)
420418
expect(uids.two.before).toBe(uids.two.after)
421419
})
422-
423-
test('should teardown in-scope effects', async () => {
424-
let resolve: (val?: any) => void
425-
const ready = new Promise(r => {
426-
resolve = r
427-
})
428-
429-
let c: ComputedRef
430-
431-
const Comp = defineComponent({
432-
async setup() {
433-
let __temp: any, __restore: any
434-
;[__temp, __restore] = withAsyncContext(() => Promise.resolve())
435-
__temp = await __temp
436-
__restore()
437-
438-
c = computed(() => {})
439-
// register the lifecycle after an await statement
440-
onMounted(resolve)
441-
return () => ''
442-
},
443-
})
444-
445-
const app = createApp(() => h(Suspense, () => h(Comp)))
446-
const root = nodeOps.createElement('div')
447-
app.mount(root)
448-
449-
await ready
450-
expect(c!.effect.active).toBe(true)
451-
452-
app.unmount()
453-
expect(c!.effect.active).toBe(false)
454-
})
455420
})
456421
})

packages/runtime-core/__tests__/apiWatch.spec.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1185,7 +1185,11 @@ describe('api: watch', () => {
11851185
await nextTick()
11861186
await nextTick()
11871187

1188-
expect(instance!.scope.effects[0].active).toBe(false)
1188+
for (const effect of instance!.scope.effects) {
1189+
if ('active' in effect) {
1190+
expect(effect.active).toBe(false)
1191+
}
1192+
}
11891193
})
11901194

11911195
test('this.$watch should pass `this.proxy` to watch source as the first argument ', () => {

packages/runtime-core/src/apiWatch.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {
22
type ComputedRef,
33
type DebuggerOptions,
44
type EffectScheduler,
5-
ReactiveEffect,
5+
ReactiveSideEffect,
66
ReactiveFlags,
77
type Ref,
88
getCurrentScope,
@@ -392,7 +392,7 @@ function doWatch(
392392
scheduler = () => queueJob(job)
393393
}
394394

395-
const effect = new ReactiveEffect(getter, NOOP, scheduler)
395+
const effect = new ReactiveSideEffect(getter, NOOP, scheduler)
396396

397397
const scope = getCurrentScope()
398398
const unwatch = () => {

0 commit comments

Comments
 (0)