Skip to content

Commit cf15197

Browse files
deletemeabdullah-wn
authored andcommitted
fix(watch): unwatch should be callable during SSR (vuejs#11925)
close vuejs#11924
1 parent a41aff7 commit cf15197

File tree

2 files changed

+43
-5
lines changed

2 files changed

+43
-5
lines changed

Diff for: packages/runtime-core/__tests__/apiWatch.spec.ts

+38
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import {
3737
toRef,
3838
triggerRef,
3939
} from '@vue/reactivity'
40+
import { renderToString } from '@vue/server-renderer'
4041

4142
describe('api: watch', () => {
4243
it('effect', async () => {
@@ -373,6 +374,43 @@ describe('api: watch', () => {
373374
expect(dummy).toBe(0)
374375
})
375376

377+
it('stopping the watcher (SSR)', async () => {
378+
let dummy = 0
379+
const count = ref<number>(1)
380+
const captureValue = (value: number) => {
381+
dummy = value
382+
}
383+
const watchCallback = vi.fn(newValue => {
384+
captureValue(newValue)
385+
})
386+
const Comp = defineComponent({
387+
created() {
388+
const getter = () => this.count
389+
captureValue(getter()) // sets dummy to 1
390+
const stop = this.$watch(getter, watchCallback)
391+
stop()
392+
this.count = 2 // shouldn't trigger side effect
393+
},
394+
render() {
395+
return h('div', this.count)
396+
},
397+
setup() {
398+
return { count }
399+
},
400+
})
401+
let html
402+
html = await renderToString(h(Comp))
403+
// should not throw here
404+
expect(html).toBe(`<div>2</div>`)
405+
expect(watchCallback).not.toHaveBeenCalled()
406+
expect(dummy).toBe(1)
407+
await nextTick()
408+
count.value = 3 // shouldn't trigger side effect
409+
await nextTick()
410+
expect(watchCallback).not.toHaveBeenCalled()
411+
expect(dummy).toBe(1)
412+
})
413+
376414
it('stopping the watcher (with source)', async () => {
377415
const state = reactive({ count: 0 })
378416
let dummy

Diff for: packages/runtime-core/src/apiWatch.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,11 @@ function doWatch(
210210
// immediately watch or watchEffect
211211
baseWatchOptions.once = true
212212
} else {
213-
return {
214-
stop: NOOP,
215-
resume: NOOP,
216-
pause: NOOP,
217-
} as WatchHandle
213+
const watchStopHandle = () => {}
214+
watchStopHandle.stop = NOOP
215+
watchStopHandle.resume = NOOP
216+
watchStopHandle.pause = NOOP
217+
return watchStopHandle
218218
}
219219
}
220220

0 commit comments

Comments
 (0)