fix(useTemplateRef): fix readonly warning when useTemplateRef has same variable name as template ref

close #11795
close #11802
close #11804
This commit is contained in:
Evan You 2024-09-04 20:53:12 +08:00
parent 7518bc19dc
commit bc63df0199
No known key found for this signature in database
GPG Key ID: 00E9AB7A6704CE0A
2 changed files with 32 additions and 4 deletions

View File

@ -82,4 +82,25 @@ describe('useTemplateRef', () => {
expect(`useTemplateRef('foo') already exists.`).toHaveBeenWarned()
})
// #11795
test('should work when variable name is same as key', () => {
let tRef
const key = 'refKey'
const Comp = {
setup() {
tRef = useTemplateRef(key)
return {
[key]: tRef,
}
},
render() {
return h('div', { ref: key })
},
}
const root = nodeOps.createElement('div')
render(h(Comp), root)
expect('target is readonly').not.toHaveBeenWarned()
})
})

View File

@ -63,12 +63,18 @@ export function setRef(
const oldRef = oldRawRef && (oldRawRef as VNodeNormalizedRefAtom).r
const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs
const setupState = owner.setupState
const canSetSetupRef =
setupState === EMPTY_OBJ
? () => false
: (key: string) =>
hasOwn(setupState, key) &&
!(Object.getOwnPropertyDescriptor(refs, key) || EMPTY_OBJ).get
// dynamic ref changed. unset old ref
if (oldRef != null && oldRef !== ref) {
if (isString(oldRef)) {
refs[oldRef] = null
if (hasOwn(setupState, oldRef)) {
if (canSetSetupRef(oldRef)) {
setupState[oldRef] = null
}
} else if (isRef(oldRef)) {
@ -81,11 +87,12 @@ export function setRef(
} else {
const _isString = isString(ref)
const _isRef = isRef(ref)
if (_isString || _isRef) {
const doSet = () => {
if (rawRef.f) {
const existing = _isString
? hasOwn(setupState, ref)
? canSetSetupRef(ref)
? setupState[ref]
: refs[ref]
: ref.value
@ -95,7 +102,7 @@ export function setRef(
if (!isArray(existing)) {
if (_isString) {
refs[ref] = [refValue]
if (hasOwn(setupState, ref)) {
if (canSetSetupRef(ref)) {
setupState[ref] = refs[ref]
}
} else {
@ -108,7 +115,7 @@ export function setRef(
}
} else if (_isString) {
refs[ref] = value
if (hasOwn(setupState, ref)) {
if (canSetSetupRef(ref)) {
setupState[ref] = value
}
} else if (_isRef) {