标准答案
- 模板 ref 可以通过 ref 属性拿到 DOM 元素或组件实例,通常要等组件 mounted 后才可用。
- DOM ref 适合聚焦输入框、测量尺寸、滚动容器、接入第三方 DOM 库。
- 组件 ref 适合调用子组件显式暴露的方法,例如表单 validate、弹窗 open、播放器 play。
- script setup 中子组件默认不会把内部变量都暴露给父组件,需要子组件用 defineExpose 明确暴露。
- useTemplateRef 可以用模板中的 ref 名称创建对应引用,减少手写 ref(null) 和类型声明的重复。
题目解析
ref 是逃出声明式数据流的工具,应该用在确实需要 DOM 或命令式能力的地方。
能用 props / emits 表达的数据流,不要用组件 ref 强行调用子组件内部方法。
访问模板 ref 的时机很重要。setup 同步阶段还没有 DOM,mounted 或 nextTick 后再读更稳。
代码示例
输入框自动聚焦适合使用 DOM ref;调用子组件校验适合使用组件 ref 和 defineExpose。
Vue
<script setup lang="ts">
import { onMounted, ref } from 'vue'
const inputRef = ref<HTMLInputElement | null>(null)
onMounted(() => {
inputRef.value?.focus()
})
</script>
<template>
<input ref="inputRef" type="text">
</template>常见误区
- 在 setup 同步阶段直接读取 DOM ref,结果拿到 null。
- 父组件通过 ref 调子组件内部方法,但子组件没有 defineExpose。
- 能用 props 和 emits 完成的状态同步,改用组件 ref 直接改子组件内部状态。