]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(watch): unwatch should be callable during SSR (#11925)
authorMatt Garrett <mattga@gmail.com>
Mon, 16 Sep 2024 02:49:16 +0000 (19:49 -0700)
committerGitHub <noreply@github.com>
Mon, 16 Sep 2024 02:49:16 +0000 (10:49 +0800)
close #11924

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

index 7a800949eea8983592ed632f153f71ce1d6b0a5f..082d585b85278dcfa005dc7ff8bdb2807001b5b1 100644 (file)
@@ -37,6 +37,7 @@ import {
   toRef,
   triggerRef,
 } from '@vue/reactivity'
+import { renderToString } from '@vue/server-renderer'
 
 describe('api: watch', () => {
   it('effect', async () => {
@@ -373,6 +374,43 @@ describe('api: watch', () => {
     expect(dummy).toBe(0)
   })
 
+  it('stopping the watcher (SSR)', async () => {
+    let dummy = 0
+    const count = ref<number>(1)
+    const captureValue = (value: number) => {
+      dummy = value
+    }
+    const watchCallback = vi.fn(newValue => {
+      captureValue(newValue)
+    })
+    const Comp = defineComponent({
+      created() {
+        const getter = () => this.count
+        captureValue(getter()) // sets dummy to 1
+        const stop = this.$watch(getter, watchCallback)
+        stop()
+        this.count = 2 // shouldn't trigger side effect
+      },
+      render() {
+        return h('div', this.count)
+      },
+      setup() {
+        return { count }
+      },
+    })
+    let html
+    html = await renderToString(h(Comp))
+    // should not throw here
+    expect(html).toBe(`<div>2</div>`)
+    expect(watchCallback).not.toHaveBeenCalled()
+    expect(dummy).toBe(1)
+    await nextTick()
+    count.value = 3 // shouldn't trigger side effect
+    await nextTick()
+    expect(watchCallback).not.toHaveBeenCalled()
+    expect(dummy).toBe(1)
+  })
+
   it('stopping the watcher (with source)', async () => {
     const state = reactive({ count: 0 })
     let dummy
index a14823beb6256202eb2e35e21b1d66dd9b08c937..798b6e7261b7ac9205c8e96696065abeb4560a8c 100644 (file)
@@ -179,11 +179,11 @@ function doWatch(
       // immediately watch or watchEffect
       baseWatchOptions.once = true
     } else {
-      return {
-        stop: NOOP,
-        resume: NOOP,
-        pause: NOOP,
-      } as WatchHandle
+      const watchStopHandle = () => {}
+      watchStopHandle.stop = NOOP
+      watchStopHandle.resume = NOOP
+      watchStopHandle.pause = NOOP
+      return watchStopHandle
     }
   }