From: daiwei Date: Tue, 18 Feb 2025 08:48:31 +0000 (+0800) Subject: feat(useTemplateRef): allows useTemplateRef to be called multiple times using the... X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=09b25f14bc0c5e167f456fb6f2aa3ee9d09b5546;p=thirdparty%2Fvuejs%2Fcore.git feat(useTemplateRef): allows useTemplateRef to be called multiple times using the same key --- diff --git a/packages/runtime-core/__tests__/helpers/useTemplateRef.spec.ts b/packages/runtime-core/__tests__/helpers/useTemplateRef.spec.ts index adc8ed66c7..d016122523 100644 --- a/packages/runtime-core/__tests__/helpers/useTemplateRef.spec.ts +++ b/packages/runtime-core/__tests__/helpers/useTemplateRef.spec.ts @@ -70,18 +70,22 @@ describe('useTemplateRef', () => { expect(t1!.value).toBe(null) }) - test('should warn on duplicate useTemplateRef', () => { + test('should return same element for multiple useTemplateRef calls with same key', async () => { + let t1, t2 + const key = ref('foo') const root = nodeOps.createElement('div') render( h(() => { - useTemplateRef('foo') - useTemplateRef('foo') - return '' + t1 = useTemplateRef('foo') + t2 = useTemplateRef('foo') + return h('div', { ref: key.value }) }), root, ) - - expect(`useTemplateRef('foo') already exists.`).toHaveBeenWarned() + await nextTick() + expect(t1!.value).toBe(root.children[0]) + expect(t2!.value).toBe(root.children[0]) + expect(t1!.value).toBe(t2!.value) }) // #11795 diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index 3ed42ed0b5..4c471ce9cb 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -2,6 +2,7 @@ import { type VNode, type VNodeChild, isVNode } from './vnode' import { EffectScope, type ReactiveEffect, + type ShallowRef, TrackOpTypes, isRef, markRaw, @@ -461,6 +462,12 @@ export interface ComponentInternalInstance { refs: Data emit: EmitFn + /** + * used for caching useTemplateRef results + * @internal + */ + refsCache?: Map + /** * used for keeping track of .once event handlers on components * @internal diff --git a/packages/runtime-core/src/helpers/useTemplateRef.ts b/packages/runtime-core/src/helpers/useTemplateRef.ts index 4cb10ea813..aa31c29c22 100644 --- a/packages/runtime-core/src/helpers/useTemplateRef.ts +++ b/packages/runtime-core/src/helpers/useTemplateRef.ts @@ -12,14 +12,12 @@ export function useTemplateRef( const r = shallowRef(null) if (i) { const refs = i.refs === EMPTY_OBJ ? (i.refs = {}) : i.refs - let desc: PropertyDescriptor | undefined - if ( - __DEV__ && - (desc = Object.getOwnPropertyDescriptor(refs, key)) && - !desc.configurable - ) { - warn(`useTemplateRef('${key}') already exists.`) + const refsCache = + i.refsCache || (i.refsCache = new Map()) + if (refsCache.has(key)) { + return refsCache.get(key)! } else { + refsCache.set(key, r) Object.defineProperty(refs, key, { enumerable: true, get: () => r.value,