Vue 的 ref 必须绑定在模板的具体元素或组件标签上,组件挂载后方可安全使用。它主要用于访问原生 DOM 节点或子组件实例,并支持聚焦、滚动、尺寸测量以及调用通过 expose 暴露的方法。

Vue 的 ref 是访问组件实例与 DOM 节点最直接、最可控的方式,但并非万能钩子,正确把握使用时机与方法才能真正发挥其作用。
先从基础说起。ref 绑定的规则并不复杂,牢记以下三个关键点即可。
第一,ref 必须绑定在模板中的具体元素或组件标签上,名称需唯一且符合变量命名规范。例如,为普通 DOM 元素绑定 ,即可获取原生 DOM 节点;为自定义组件绑定 ,则可获得该组件的实例,包括其 methods 和通过 expose 暴露出的内容。
第二,避免直接在 v-for 生成的多个同名 ref 上使用,因为值会被覆盖。若需批量操作,建议改用 ref 函数或配合 querySelectorAll 处理。
总结:绑定要找准位置,命名要规范,批量操作要换思路。
那么,何时才能安全使用 ref?
答案是:只能在组件挂载之后。ref 对应的值在组件挂载后才由 Vue 注入,渲染前访问只能得到 null 或 undefined。具体到不同 API,用法略有差异:
- 选项 API:需在
mounted()钩子内使用this.$refs.xxx引用。 - 组合 API(
setup):先声明const xxx = ref(null),再在onMounted中读取xxx.value。 - 切记:不要在
created或beforeMount中尝试读取,因为 DOM 尚未生成,读取无效。
一句话总结:时机正确、方法得当,ref 才能真正派上用场。
在实际开发中,最常见的应用场景包括聚焦、滚动和尺寸测量。这些操作无需任何第三方库,直接使用 ref 即可实现:
- 让输入框自动获得焦点:
this.$refs.inputEl.focus() - 滚动到底部:
this.$refs.listEl.scrollTop = this.$refs.listEl.scrollHeight - 获取元素宽高位置:
this.$refs.boxEl.getBoundingClientRect()
注意:这些操作不会触发 Vue 的响应式更新,也不受 Vue 监控,属于纯粹的 DOM 行为。简单来说,就是直接操作底层,框架不干涉。
再介绍一个高阶用法:通过 ref 调用子组件的方法。
这本质上是打破单向数据流的临时通道,适用于强耦合、明确控制的场景。但需注意边界:
- 子组件必须显式暴露方法。Vue3 使用
defineExpose,Vue2 默认全部公开。 - 父组件调用时,写法如下:
this.$refs.childComp.submitForm()或childRef.value?.submitForm()。 - 务必避免在子组件内部频繁监听父 ref 的变化,这并非响应式机制,也不推荐反向依赖。
- 一旦通信变得复杂(如多层嵌套或事件分散),应优先考虑
emit、provide/inject或状态管理方案。
总结:ref 是一把利器,用得好坏取决于时机与边界。瞄准目标、规范使用,它将成为你最得心应手的工具。
