标准答案

  1. 模板 ref 可以通过 ref 属性拿到 DOM 元素或组件实例,通常要等组件 mounted 后才可用。
  2. DOM ref 适合聚焦输入框、测量尺寸、滚动容器、接入第三方 DOM 库。
  3. 组件 ref 适合调用子组件显式暴露的方法,例如表单 validate、弹窗 open、播放器 play。
  4. script setup 中子组件默认不会把内部变量都暴露给父组件,需要子组件用 defineExpose 明确暴露。
  5. 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 直接改子组件内部状态。

作者信息