diff --git a/packages/runtime-core/__tests__/helpers/useTemplateRef.spec.ts b/packages/runtime-core/__tests__/helpers/useTemplateRef.spec.ts index 10de6f48353..e590a719946 100644 --- a/packages/runtime-core/__tests__/helpers/useTemplateRef.spec.ts +++ b/packages/runtime-core/__tests__/helpers/useTemplateRef.spec.ts @@ -90,12 +90,14 @@ describe('useTemplateRef', () => { const Comp = { setup() { tRef = useTemplateRef(key) + const foo = useTemplateRef('bar') return { [key]: tRef, + foo, } }, render() { - return h('div', { ref: key }) + return [h('div', { ref: key }), h('div', { ref: 'foo' })] }, } const root = nodeOps.createElement('div') diff --git a/packages/runtime-core/src/component.ts b/packages/runtime-core/src/component.ts index cccb7280fd4..b6f47b79b51 100644 --- a/packages/runtime-core/src/component.ts +++ b/packages/runtime-core/src/component.ts @@ -940,6 +940,10 @@ export function handleSetupResult( } instance.setupState = proxyRefs(setupResult) if (__DEV__) { + // dev only + Object.defineProperty(setupResult, '__v__setupResult', { + value: setupResult, + }) exposeSetupStateOnRenderContext(instance) } } else if (__DEV__ && setupResult !== undefined) { diff --git a/packages/runtime-core/src/helpers/useTemplateRef.ts b/packages/runtime-core/src/helpers/useTemplateRef.ts index 58c109a9246..b15d52e6fd5 100644 --- a/packages/runtime-core/src/helpers/useTemplateRef.ts +++ b/packages/runtime-core/src/helpers/useTemplateRef.ts @@ -8,6 +8,8 @@ export function useTemplateRef( ): Readonly> { const i = getCurrentInstance() const r = shallowRef(null) + // @ts-expect-error + r.__v__TemplateRef = true if (i) { const refs = i.refs === EMPTY_OBJ ? (i.refs = {}) : i.refs diff --git a/packages/runtime-core/src/rendererTemplateRef.ts b/packages/runtime-core/src/rendererTemplateRef.ts index c7b15fe4022..f961f1219b2 100644 --- a/packages/runtime-core/src/rendererTemplateRef.ts +++ b/packages/runtime-core/src/rendererTemplateRef.ts @@ -66,9 +66,22 @@ export function setRef( const canSetSetupRef = setupState === EMPTY_OBJ ? () => false - : (key: string) => - hasOwn(setupState, key) && - !(Object.getOwnPropertyDescriptor(refs, key) || EMPTY_OBJ).get + : (key: string) => { + if (!hasOwn(setupState, key)) return false + if (__DEV__) { + if ( + setupState.__v__setupResult && + // @ts-expect-error + setupState.__v__setupResult[ref] && + // @ts-expect-error + setupState.__v__setupResult[ref].__v__TemplateRef + ) { + return false + } + return true + } + return true + } // dynamic ref changed. unset old ref if (oldRef != null && oldRef !== ref) { @@ -118,7 +131,9 @@ export function setRef( if (canSetSetupRef(ref)) { setupState[ref] = value } - } else if (_isRef) { + } + // @ts-expect-error + else if (_isRef && !ref.__v__TemplateRef) { ref.value = value if (rawRef.k) refs[rawRef.k] = value } else if (__DEV__) {