Skip to content

Commit 2fec5d6

Browse files
committed
chore: update
1 parent d1c10b2 commit 2fec5d6

File tree

2 files changed

+51
-8
lines changed

2 files changed

+51
-8
lines changed

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,44 @@ describe('api: template refs', () => {
225225
expect(el.value).toBe(null)
226226
})
227227

228+
it('set and change ref in the same tick', async () => {
229+
const root = nodeOps.createElement('div')
230+
const show = ref(false)
231+
const refName = ref('a')
232+
233+
const Child = defineComponent({
234+
setup() {
235+
refName.value = 'b'
236+
return () => {}
237+
},
238+
})
239+
240+
const Comp = {
241+
render() {
242+
return h(Child, {
243+
ref: refName.value,
244+
})
245+
},
246+
updated(this: any) {
247+
expect(this.$refs.a).toBe(null)
248+
expect(this.$refs.b).not.toBe(null)
249+
},
250+
}
251+
252+
const App = {
253+
render() {
254+
return show.value ? h(Comp) : null
255+
},
256+
}
257+
258+
render(h(App), root)
259+
expect(refName.value).toBe('a')
260+
261+
show.value = true
262+
await nextTick()
263+
expect(refName.value).toBe('b')
264+
})
265+
228266
test('string ref inside slots', async () => {
229267
const root = nodeOps.createElement('div')
230268
const spy = vi.fn()

packages/runtime-core/src/rendererTemplateRef.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { queuePostRenderEffect } from './renderer'
1818
import { type ComponentOptions, getComponentPublicInstance } from './component'
1919
import { knownTemplateRefs } from './helpers/useTemplateRef'
2020

21-
const pendingSetRefMap = new WeakMap<VNode, SchedulerJob>()
21+
const pendingSetRefMap = new WeakMap<VNodeNormalizedRef, SchedulerJob>()
2222
/**
2323
* Function for handling a template ref
2424
*/
@@ -97,6 +97,7 @@ export function setRef(
9797

9898
// dynamic ref changed. unset old ref
9999
if (oldRef != null && oldRef !== ref) {
100+
invalidatePendingSetRef(oldRawRef!)
100101
if (isString(oldRef)) {
101102
refs[oldRef] = null
102103
if (canSetSetupRef(oldRef)) {
@@ -156,21 +157,25 @@ export function setRef(
156157
// ref with the same key
157158
const job: SchedulerJob = () => {
158159
doSet()
159-
pendingSetRefMap.delete(vnode)
160+
pendingSetRefMap.delete(rawRef)
160161
}
161162
job.id = -1
162-
pendingSetRefMap.set(vnode, job)
163+
pendingSetRefMap.set(rawRef, job)
163164
queuePostRenderEffect(job, parentSuspense)
164165
} else {
165-
const pendingSetRef = pendingSetRefMap.get(vnode)
166-
if (pendingSetRef) {
167-
pendingSetRef.flags! |= SchedulerJobFlags.DISPOSED
168-
pendingSetRefMap.delete(vnode)
169-
}
166+
invalidatePendingSetRef(rawRef)
170167
doSet()
171168
}
172169
} else if (__DEV__) {
173170
warn('Invalid template ref type:', ref, `(${typeof ref})`)
174171
}
175172
}
176173
}
174+
175+
function invalidatePendingSetRef(rawRef: VNodeNormalizedRef) {
176+
const pendingSetRef = pendingSetRefMap.get(rawRef)
177+
if (pendingSetRef) {
178+
pendingSetRef.flags! |= SchedulerJobFlags.DISPOSED
179+
pendingSetRefMap.delete(rawRef)
180+
}
181+
}

0 commit comments

Comments
 (0)