vue.js模板引用需在setup中用ref(null)初始化并暴露,模板用ref="xxx"绑定,挂载后通过onmounted或watch安全访问;动态列表用函数式ref,子组件需defineexpose才可调用方法。

Vue.js 的模板引用(Template Refs)是访问 DOM 元素或子组件实例的最直接方式,尤其在组合式 API(setup())中,它替代了旧版的 this.$refs,更契合响应式逻辑。关键在于正确声明、安全访问和避免常见陷阱。
如何正确定义和绑定 template ref
在模板中使用 ref 属性绑定一个响应式引用,在 setup() 中用 ref(null) 初始化,并确保变量名与模板中的 ref 值完全一致(区分大小写、无空格):
- 模板中:
<input ref="inputRef"> - 脚本中:
const inputRef = ref(null),且必须在return或expose中暴露(若为子组件) - 不支持动态 ref 名(如
:ref="'input' + index"),需用函数式 ref 处理多个元素
在生命周期中安全读取 ref 值
DOM 元素仅在组件挂载后才存在,因此不能在 setup() 同步代码中立即访问 inputRef.value:
递归分析 Vue 项目组件依赖,从入口文件生成组件层级图,支持 Vue 2/3,输出组件名、文件路径和属性。适用于分析组件结构、排查依赖或了解项目架构。
- 推荐在
onMounted钩子中首次操作:例如inputRef.value?.focus() - 对异步更新的 ref(如 v-if 切换后出现),可用
watch监听其变化:watch(inputRef, (el) => { if (el) el.focus() }) - 避免在
onBeforeMount中访问,此时 DOM 尚未生成
函数式 ref 处理动态/列表元素
当需要为 v-for 渲染的多个元素分别绑定 ref,或需在元素创建/销毁时执行逻辑,应使用函数式 ref:
- 写法:
<div v-for="item in list" :key="item.id" :ref="el => { if (el) divRefs.push(el) }"> <li>配合 <code>onBeforeUnmount清理数组引用,防止内存泄漏 - 注意:函数会被调用两次(挂载时传入元素,卸载时传入 null),需做空值判断
- 子组件中:
defineExpose({ focusInput(), reset() }) - 父组件中:
childRef.value?.focusInput(),类型提示需配合InstanceType<typeof childcomponent></typeof> - 不暴露的方法无法通过 ref 调用,这是 Vue 的封装保护机制
访问子组件实例及其方法
template ref 也可指向子组件,前提是子组件显式暴露方法(通过 defineExpose):










