]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(reactivity): prevent endless recursion in computed getters (#11797)
authorJürg Lehni <juerg@scratchdisk.com>
Thu, 5 Sep 2024 10:54:30 +0000 (12:54 +0200)
committerGitHub <noreply@github.com>
Thu, 5 Sep 2024 10:54:30 +0000 (18:54 +0800)
packages/reactivity/__tests__/computed.spec.ts
packages/reactivity/src/dep.ts

index c3409eee77e68ba380731843732aa47d0e120cd1..31daef559a8115a043efe3a8316d7f21f8561c63 100644 (file)
@@ -1,4 +1,6 @@
 import {
+  type TestElement,
+  defineComponent,
   h,
   nextTick,
   nodeOps,
@@ -6,6 +8,7 @@ import {
   onUnmounted,
   render,
   serializeInner,
+  triggerEvent,
 } from '@vue/runtime-test'
 import {
   type DebuggerEvent,
@@ -958,4 +961,46 @@ describe('reactivity/computed', () => {
       newValue: 2,
     })
   })
+
+  test('should prevent endless recursion in self-referencing computed getters', async () => {
+    const Comp = defineComponent({
+      data() {
+        return {
+          counter: 0,
+        }
+      },
+
+      computed: {
+        message(): string {
+          if (this.counter === 0) {
+            this.counter++
+            return this.message
+          } else {
+            return `Step ${this.counter}`
+          }
+        },
+      },
+
+      render() {
+        return [
+          h(
+            'button',
+            {
+              onClick: () => {
+                this.counter++
+              },
+            },
+            'Step',
+          ),
+          h('p', this.message),
+        ]
+      },
+    })
+    const root = nodeOps.createElement('div')
+    render(h(Comp), root)
+    expect(serializeInner(root)).toBe(`<button>Step</button><p></p>`)
+    triggerEvent(root.children[1] as TestElement, 'click')
+    await nextTick()
+    expect(serializeInner(root)).toBe(`<button>Step</button><p>Step 2</p>`)
+  })
 })
index 4ce73ac995439c8f4488b88fcef7a3d1a777fe7b..6d938cbc25fe225858361dc8b375f3960bee0e52 100644 (file)
@@ -46,7 +46,7 @@ export class Dep {
   }
 
   track(debugInfo?: DebuggerEventExtraInfo): Link | undefined {
-    if (!activeSub || !shouldTrack) {
+    if (!activeSub || !shouldTrack || activeSub === this.computed) {
       return
     }