]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(runtime-core): unset old ref during patching when new ref is absent (#12900)
authorinottn <inottn@outlook.com>
Thu, 5 Jun 2025 02:19:48 +0000 (10:19 +0800)
committerGitHub <noreply@github.com>
Thu, 5 Jun 2025 02:19:48 +0000 (10:19 +0800)
fix #12898

packages/runtime-core/__tests__/rendererTemplateRef.spec.ts
packages/runtime-core/src/renderer.ts

index a7ae7a06bfd4f30f21957325a7f4549170d174fc..7803826e3df2d37d28814bb9588c7a0c574cbce8 100644 (file)
@@ -179,6 +179,37 @@ describe('api: template refs', () => {
     expect(el.value).toBe(null)
   })
 
+  it('unset old ref when new ref is absent', async () => {
+    const root1 = nodeOps.createElement('div')
+    const root2 = nodeOps.createElement('div')
+    const el1 = ref(null)
+    const el2 = ref(null)
+    const toggle = ref(true)
+
+    const Comp1 = {
+      setup() {
+        return () => (toggle.value ? h('div', { ref: el1 }) : h('div'))
+      },
+    }
+
+    const Comp2 = {
+      setup() {
+        return () => h('div', { ref: toggle.value ? el2 : undefined })
+      },
+    }
+
+    render(h(Comp1), root1)
+    render(h(Comp2), root2)
+
+    expect(el1.value).toBe(root1.children[0])
+    expect(el2.value).toBe(root2.children[0])
+
+    toggle.value = false
+    await nextTick()
+    expect(el1.value).toBe(null)
+    expect(el2.value).toBe(null)
+  })
+
   test('string ref inside slots', async () => {
     const root = nodeOps.createElement('div')
     const spy = vi.fn()
index 56f9759bc55123089cc28ca1e16a8cecdc9c5cef..a57be791a44eb807796520ea2833bc2ea7ee6cbe 100644 (file)
@@ -485,6 +485,8 @@ function baseCreateRenderer(
     // set ref
     if (ref != null && parentComponent) {
       setRef(ref, n1 && n1.ref, parentSuspense, n2 || n1, !n2)
+    } else if (ref == null && n1 && n1.ref != null) {
+      setRef(n1.ref, null, parentSuspense, n1, true)
     }
   }