From f94a0c0e1c6a25929d3aed241d049ec84492611f Mon Sep 17 00:00:00 2001 From: tsiotska Date: Fri, 25 Oct 2024 14:15:37 +0300 Subject: [PATCH 1/3] test(templateRef): multiple elements with same ref --- .../__tests__/helpers/useTemplateRef.spec.ts | 24 +++++++++++++++++++ .../__tests__/rendererTemplateRef.spec.ts | 24 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/packages/runtime-core/__tests__/helpers/useTemplateRef.spec.ts b/packages/runtime-core/__tests__/helpers/useTemplateRef.spec.ts index adc8ed66c77..3dc0005bf6e 100644 --- a/packages/runtime-core/__tests__/helpers/useTemplateRef.spec.ts +++ b/packages/runtime-core/__tests__/helpers/useTemplateRef.spec.ts @@ -125,4 +125,28 @@ describe('useTemplateRef', () => { __DEV__ = true } }) + + // 12246 + test('should set last element if multiple with same key are defined', () => { + let tRef: ShallowRef + let key = 'refKey' + + const Comp = { + setup() { + tRef = useTemplateRef(key) + }, + render() { + return h('div', [ + h('div', { ref: key }), + h('div', { ref: key }), + h('span', { ref: key }), + ]) + }, + } + + const root = nodeOps.createElement('div') + render(h(Comp), root) + + expect(tRef!.value.tag).toBe('span') + }) }) diff --git a/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts b/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts index 64cb9c63014..68f24055c1c 100644 --- a/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts +++ b/packages/runtime-core/__tests__/rendererTemplateRef.spec.ts @@ -1,4 +1,5 @@ import { + type ShallowRef, defineComponent, h, nextTick, @@ -538,4 +539,27 @@ describe('api: template refs', () => { '
[object Object],[object Object]
', ) }) + + // 12246 + test('should set last element if multiple with same key are defined', () => { + let refKey: ShallowRef + + const Comp = { + setup() { + refKey = ref() + }, + render() { + return h('div', [ + h('div', { ref: refKey }), + h('div', { ref: refKey }), + h('span', { ref: refKey }), + ]) + }, + } + + const root = nodeOps.createElement('div') + render(h(Comp), root) + + expect(refKey!.value.tag).toBe('span') + }) }) From 161939a83c8c9d1e47468c661ac2483db751f935 Mon Sep 17 00:00:00 2001 From: tsiotska Date: Fri, 25 Oct 2024 19:27:30 +0300 Subject: [PATCH 2/3] fix(useTemplateRef): multiple refs with the same key close #12246 --- packages/runtime-core/src/rendererTemplateRef.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/runtime-core/src/rendererTemplateRef.ts b/packages/runtime-core/src/rendererTemplateRef.ts index bffe1a25321..c44f7955719 100644 --- a/packages/runtime-core/src/rendererTemplateRef.ts +++ b/packages/runtime-core/src/rendererTemplateRef.ts @@ -115,9 +115,11 @@ export function setRef( } else { if (!isArray(existing)) { if (_isString) { - refs[ref] = [refValue] - if (canSetSetupRef(ref)) { - setupState[ref] = refs[ref] + if (oldRef !== ref) { + refs[ref] = [refValue] + if (canSetSetupRef(ref)) { + setupState[ref] = refs[ref] + } } } else { ref.value = [refValue] @@ -128,9 +130,11 @@ export function setRef( } } } else if (_isString) { - refs[ref] = value - if (canSetSetupRef(ref)) { - setupState[ref] = value + if (oldRef !== ref) { + refs[ref] = value + if (canSetSetupRef(ref)) { + setupState[ref] = value + } } } else if (_isRef) { ref.value = value From 5e273d10c15c565fd2dd11ed4682059fa26d37e5 Mon Sep 17 00:00:00 2001 From: tsiotska Date: Mon, 28 Oct 2024 14:46:39 +0200 Subject: [PATCH 3/3] chore(rendererTemplateRef): added dev warning for duplicated ref --- .../runtime-core/src/rendererTemplateRef.ts | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/packages/runtime-core/src/rendererTemplateRef.ts b/packages/runtime-core/src/rendererTemplateRef.ts index c44f7955719..29e5d3c0c13 100644 --- a/packages/runtime-core/src/rendererTemplateRef.ts +++ b/packages/runtime-core/src/rendererTemplateRef.ts @@ -115,11 +115,19 @@ export function setRef( } else { if (!isArray(existing)) { if (_isString) { - if (oldRef !== ref) { - refs[ref] = [refValue] - if (canSetSetupRef(ref)) { - setupState[ref] = refs[ref] + if (oldRef === ref) { + if (__DEV__ && !__TEST__) { + warn( + 'Duplicate template ref detected:', + ref, + `(${typeof ref}). Ref names must be unique within the same scope.`, + ) } + return + } + refs[ref] = [refValue] + if (canSetSetupRef(ref)) { + setupState[ref] = refs[ref] } } else { ref.value = [refValue] @@ -130,11 +138,19 @@ export function setRef( } } } else if (_isString) { - if (oldRef !== ref) { - refs[ref] = value - if (canSetSetupRef(ref)) { - setupState[ref] = value + if (oldRef === ref) { + if (__DEV__ && !__TEST__) { + warn( + 'Duplicate template ref detected:', + ref, + `(${typeof ref}). Ref names must be unique within the same scope.`, + ) } + return + } + refs[ref] = value + if (canSetSetupRef(ref)) { + setupState[ref] = value } } else if (_isRef) { ref.value = value