Vue 3 中 ref 获取 DOM 或子组件实例需声明 ref(null),模板用 ref="xxx" 绑定,onMounted 后通过 .value 访问;子组件须 defineExpose 才能暴露属性;v-for 中 ref 自动为数组,应避免依赖顺序。

在 Vue 3 的 Composition API 中,ref 获取 DOM 元素或子组件实例的核心逻辑是:先声明一个 ref(null) 变量,模板中用同名 ref="xxx" 绑定,再在合适的时机(如 onMounted)通过 .value 访问真实对象。 它不是自动同步的,必须等 DOM 渲染完成才能拿到有效引用。
获取 DOM 元素(如 input、div、canvas)
这是最常见场景。关键点是:ref 变量初始值为 null,且必须等挂载后才能读取 .value。
- 在
<template>中直接写ref="inputRef"(不用:ref或v-bind:ref) - 在
<script setup>中用const inputRef = ref(null)声明 - 在
onMounted或nextTick中访问inputRef.value.focus()等原生 DOM 方法 - 示例:
<input ref="inputRef" type="text">→inputRef.value.value可读取输入值
获取子组件实例(调用子组件方法或属性)
父组件要操作子组件内部逻辑时,需确保子组件暴露了可被访问的属性或方法(通过 defineExpose)。
- 子组件需显式调用
defineExpose({ count, increment }),否则.value是空对象 - 父组件模板中写
<ChildComponent ref="childRef" /> - 父组件声明
const childRef = ref(null),并在onMounted后调用childRef.value.increment() - 注意:子组件未
defineExpose时,childRef.value存在但无法访问内部响应式数据
处理 v-for 列表中的多个元素
当需要批量操作一组 DOM 节点(如多个 <li>),ref 会自动变为数组,但顺序不严格保证。
- 模板中保持
ref="itemRefs"与v-for同级 - 脚本中声明
const itemRefs = ref([])(初始为空数组) - 在
onMounted或watchEffect中检查itemRefs.value.length > 0再操作 - 不建议依赖索引顺序;如需精确映射,可用
Map或给每个元素加唯一 key 配合ref函数动态绑定
安全访问的时机选择
不能在 setup() 同步执行时读取 .value,因为此时 DOM 还未生成。可靠方式有:
-
onMounted:最常用,适合初始化聚焦、尺寸测量等 -
nextTick:适合在响应式更新后立即操作 DOM(比如更新列表后滚动到底部) -
watchEffect:监听ref变化,适合“有就做,没有就等”的场景 -
watch:监听ref的变化,适合需要区分前后值的逻辑


















