]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
chore: update
authordaiwei <daiwei521@126.com>
Wed, 28 May 2025 08:47:57 +0000 (16:47 +0800)
committerdaiwei <daiwei521@126.com>
Wed, 28 May 2025 08:47:57 +0000 (16:47 +0800)
packages/runtime-core/__tests__/rendererTemplateRef.spec.ts
packages/runtime-core/src/rendererTemplateRef.ts

index ae30878a4fcf48c46a1638a6ab60406ccdf827e4..b9e5740d08c33489bfe90043411481a5b8db44e5 100644 (file)
@@ -225,6 +225,44 @@ describe('api: template refs', () => {
     expect(el.value).toBe(null)
   })
 
+  it('set and change ref in the same tick', async () => {
+    const root = nodeOps.createElement('div')
+    const show = ref(false)
+    const refName = ref('a')
+
+    const Child = defineComponent({
+      setup() {
+        refName.value = 'b'
+        return () => {}
+      },
+    })
+
+    const Comp = {
+      render() {
+        return h(Child, {
+          ref: refName.value,
+        })
+      },
+      updated(this: any) {
+        expect(this.$refs.a).toBe(null)
+        expect(this.$refs.b).not.toBe(null)
+      },
+    }
+
+    const App = {
+      render() {
+        return show.value ? h(Comp) : null
+      },
+    }
+
+    render(h(App), root)
+    expect(refName.value).toBe('a')
+
+    show.value = true
+    await nextTick()
+    expect(refName.value).toBe('b')
+  })
+
   test('string ref inside slots', async () => {
     const root = nodeOps.createElement('div')
     const spy = vi.fn()
index 0e40c9534caf8af63c6e497bec22e68645c6c690..0241aa528ec5ba7157f7cd65bde58db77341bda4 100644 (file)
@@ -18,7 +18,7 @@ import { queuePostRenderEffect } from './renderer'
 import { type ComponentOptions, getComponentPublicInstance } from './component'
 import { knownTemplateRefs } from './helpers/useTemplateRef'
 
-const pendingSetRefMap = new WeakMap<VNode, SchedulerJob>()
+const pendingSetRefMap = new WeakMap<VNodeNormalizedRef, SchedulerJob>()
 /**
  * Function for handling a template ref
  */
@@ -97,6 +97,7 @@ export function setRef(
 
   // dynamic ref changed. unset old ref
   if (oldRef != null && oldRef !== ref) {
+    invalidatePendingSetRef(oldRawRef!)
     if (isString(oldRef)) {
       refs[oldRef] = null
       if (canSetSetupRef(oldRef)) {
@@ -156,17 +157,13 @@ export function setRef(
         // ref with the same key
         const job: SchedulerJob = () => {
           doSet()
-          pendingSetRefMap.delete(vnode)
+          pendingSetRefMap.delete(rawRef)
         }
         job.id = -1
-        pendingSetRefMap.set(vnode, job)
+        pendingSetRefMap.set(rawRef, job)
         queuePostRenderEffect(job, parentSuspense)
       } else {
-        const pendingSetRef = pendingSetRefMap.get(vnode)
-        if (pendingSetRef) {
-          pendingSetRef.flags! |= SchedulerJobFlags.DISPOSED
-          pendingSetRefMap.delete(vnode)
-        }
+        invalidatePendingSetRef(rawRef)
         doSet()
       }
     } else if (__DEV__) {
@@ -174,3 +171,11 @@ export function setRef(
     }
   }
 }
+
+function invalidatePendingSetRef(rawRef: VNodeNormalizedRef) {
+  const pendingSetRef = pendingSetRefMap.get(rawRef)
+  if (pendingSetRef) {
+    pendingSetRef.flags! |= SchedulerJobFlags.DISPOSED
+    pendingSetRefMap.delete(rawRef)
+  }
+}