const oldRef = oldRawRef && (oldRawRef as VNodeNormalizedRefAtom).r
const refs = owner.refs === EMPTY_OBJ ? (owner.refs = {}) : owner.refs
const setupState = owner.setupState
- const canSetSetupRef = validateTemplateRef(setupState)
+ const canSetSetupRef = createCanSetSetupRefChecker(setupState)
// dynamic ref changed. unset old ref
if (oldRef != null && oldRef !== ref) {
}
}
-export function validateTemplateRef(
+export function createCanSetSetupRefChecker(
setupState: Data,
): (key: string) => boolean {
const rawSetupState = toRaw(setupState)
nextTick,
reactive,
ref,
+ shallowRef,
useTemplateRef,
watchEffect,
} from '@vue/runtime-dom'
const { render } = define({
setup() {
return {
- foo: fooEl,
- bar: barEl,
+ foo: shallowRef(fooEl),
+ bar: shallowRef(barEl),
}
},
render() {
})
const { host } = render()
expect(state.refKey).toBe(host.children[0])
+ expect('Template ref "refKey" used on a non-ref value').toHaveBeenWarned()
})
test('multiple root refs', () => {
expect(html()).toBe('<div>changed</div><!--dynamic-component-->')
})
+ test('should not attempt to set when variable name is same as key', () => {
+ let tRef: ShallowRef
+ const key = 'refKey'
+ define({
+ setup() {
+ tRef = useTemplateRef('_')
+ return {
+ [key]: tRef,
+ }
+ },
+ render() {
+ const n0 = template('<div></div>')() as Element
+ createTemplateRefSetter()(n0, key)
+ return n0
+ },
+ }).render()
+ expect('target is readonly').not.toHaveBeenWarned()
+ expect(tRef!.value).toBe(null)
+ })
+
+ test('should work when used as direct ref value (compiled in prod mode)', () => {
+ __DEV__ = false
+ try {
+ let foo: ShallowRef
+ const { host } = define({
+ setup() {
+ foo = useTemplateRef('foo')
+ const n0 = template('<div></div>')() as Element
+ createTemplateRefSetter()(n0, foo)
+ return n0
+ },
+ }).render()
+ expect('target is readonly').not.toHaveBeenWarned()
+ expect(foo!.value).toBe(host.children[0])
+ } finally {
+ __DEV__ = true
+ }
+ })
+
// TODO: can not reproduce in Vapor
// // #2078
// test('handling multiple merged refs', async () => {
ErrorCodes,
type SchedulerJob,
callWithErrorHandling,
+ createCanSetSetupRefChecker,
queuePostFlushCb,
- validateTemplateRef,
warn,
} from '@vue/runtime-dom'
import {
const refs =
instance.refs === EMPTY_OBJ ? (instance.refs = {}) : instance.refs
- const canSetSetupRef = validateTemplateRef(setupState)
+ const canSetSetupRef = createCanSetSetupRefChecker(setupState)
// dynamic ref changed. unset old ref
if (oldRef != null && oldRef !== ref) {
if (isString(oldRef)) {