Skip to content

Commit 09b25f1

Browse files
committed
feat(useTemplateRef): allows useTemplateRef to be called multiple times using the same key
1 parent 0c8dd94 commit 09b25f1

File tree

3 files changed

+22
-13
lines changed

3 files changed

+22
-13
lines changed

packages/runtime-core/__tests__/helpers/useTemplateRef.spec.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,22 @@ describe('useTemplateRef', () => {
7070
expect(t1!.value).toBe(null)
7171
})
7272

73-
test('should warn on duplicate useTemplateRef', () => {
73+
test('should return same element for multiple useTemplateRef calls with same key', async () => {
74+
let t1, t2
75+
const key = ref('foo')
7476
const root = nodeOps.createElement('div')
7577
render(
7678
h(() => {
77-
useTemplateRef('foo')
78-
useTemplateRef('foo')
79-
return ''
79+
t1 = useTemplateRef('foo')
80+
t2 = useTemplateRef('foo')
81+
return h('div', { ref: key.value })
8082
}),
8183
root,
8284
)
83-
84-
expect(`useTemplateRef('foo') already exists.`).toHaveBeenWarned()
85+
await nextTick()
86+
expect(t1!.value).toBe(root.children[0])
87+
expect(t2!.value).toBe(root.children[0])
88+
expect(t1!.value).toBe(t2!.value)
8589
})
8690

8791
// #11795

packages/runtime-core/src/component.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { type VNode, type VNodeChild, isVNode } from './vnode'
22
import {
33
EffectScope,
44
type ReactiveEffect,
5+
type ShallowRef,
56
TrackOpTypes,
67
isRef,
78
markRaw,
@@ -461,6 +462,12 @@ export interface ComponentInternalInstance {
461462
refs: Data
462463
emit: EmitFn
463464

465+
/**
466+
* used for caching useTemplateRef results
467+
* @internal
468+
*/
469+
refsCache?: Map<string, ShallowRef>
470+
464471
/**
465472
* used for keeping track of .once event handlers on components
466473
* @internal

packages/runtime-core/src/helpers/useTemplateRef.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,12 @@ export function useTemplateRef<T = unknown, Keys extends string = string>(
1212
const r = shallowRef(null)
1313
if (i) {
1414
const refs = i.refs === EMPTY_OBJ ? (i.refs = {}) : i.refs
15-
let desc: PropertyDescriptor | undefined
16-
if (
17-
__DEV__ &&
18-
(desc = Object.getOwnPropertyDescriptor(refs, key)) &&
19-
!desc.configurable
20-
) {
21-
warn(`useTemplateRef('${key}') already exists.`)
15+
const refsCache =
16+
i.refsCache || (i.refsCache = new Map<string, ShallowRef>())
17+
if (refsCache.has(key)) {
18+
return refsCache.get(key)!
2219
} else {
20+
refsCache.set(key, r)
2321
Object.defineProperty(refs, key, {
2422
enumerable: true,
2523
get: () => r.value,

0 commit comments

Comments
 (0)