首页 / Vue3 入门教程 / 模板引用

Vue3 入门教程

模板引用

本教程共 40 篇 · 第 14 篇 · 更新于 2026-07-29 · 约 6 分钟阅读

VueVue3 入门教程模板引用refuseTemplateRefDOM

14. 模板引用

本节目标:学会用 ref 属性获取 DOM 元素和组件实例的直接引用,掌握 useTemplateRef 的用法。

基础用法

Vue 的声明式渲染帮你屏蔽了大部分 DOM 操作。但有时候还是需要直接访问底层 DOM 元素——比如组件挂载时让输入框自动聚焦。

用特殊的 ref 属性:

<input ref="input">

获取引用

Composition API(3.5+)

useTemplateRef() 辅助函数:

<script setup>
import { useTemplateRef, onMounted } from 'vue'

// 参数必须和模板里的 ref 值匹配
const input = useTemplateRef('my-input')

onMounted(() => {
  // 组件挂载后才能访问 DOM 元素
  input.value.focus()
})
</script>

<template>
  <input ref="my-input" />
</template>

Composition API(3.5 之前)

3.5 之前需要声明一个 ref,名字和模板 ref 属性值一致:

<script setup>
import { ref, onMounted } from 'vue'

// 声明一个 ref,名字和模板里的 ref 属性值一致
const input = ref(null)

onMounted(() => {
  // 组件挂载后 DOM 元素已绑定到 input.value
  input.value.focus()
})
</script>

<template>
  <input ref="input" />
</template>
Note

只能在组件挂载后访问 ref。模板表达式里首次渲染时它是 null

组件 ref

ref 也能用在子组件上,获取的是组件实例:

<script setup>
import { useTemplateRef, onMounted } from 'vue'
import Child from './Child.vue'

// 获取子组件实例的引用
const childRef = useTemplateRef('child')

onMounted(() => {
  // childRef.value 是 Child 组件的实例
  console.log(childRef.value)
})
</script>

<template>
  <Child ref="child" />
</template>
Warning

子组件用 Options API 或不用 <script setup> 时,父组件能访问子组件的所有属性和方法。这会让父子紧耦合,尽量用 props 和 emit 交互。

<script setup> 的组件默认是私有的——父组件通过 ref 访问不到任何东西,除非子组件用 defineExpose 显式暴露:

<script setup>
import { ref } from 'vue'

// 内部数据,默认对外不可见
const a = 1
const b = ref(2)

// 显式暴露属性,父组件通过 ref 才能访问
defineExpose({
  a,
  b
})
</script>

父组件通过 ref 拿到的实例形状是 { a: number, b: number }(ref 自动解包)。

v-for 里的 ref

refv-for 里使用时,ref 值会是数组,挂载后填充所有元素:

<script setup>
import { ref, useTemplateRef, onMounted } from 'vue'

const list = ref([/* ... */])
// v-for 里的 ref 会收集所有匹配的元素
const itemRefs = useTemplateRef('items')

onMounted(() => {
  // itemRefs.value 是包含所有 li 元素的数组
  console.log(itemRefs.value)
})
</script>

<template>
  <ul>
    <li v-for="item in list" ref="items">
      {{ item }}
    </li>
  </ul>
</template>
Note

ref 数组不保证和源数组顺序一致。

函数 ref

ref 属性也可以绑定函数,每次组件更新都会调用:

<input :ref="(el) => { /* 把 el 赋给某个属性或 ref */ }">

用动态 :ref 绑定函数而不是字符串。元素卸载时参数是 null。也可以用方法代替内联函数。

常见用途

模板引用最常见的场景:

  1. 组件挂载后聚焦输入框
onMounted(() => {
  input.value.focus()
})
  1. 初始化第三方库
onMounted(() => {
  // 用 input.value 作为第三方库的挂载点
  new ThirdPartyLib(input.value)
})
  1. 测量 DOM 元素
onMounted(() => {
  const { width, height } = input.value.getBoundingClientRect()
})

本节回顾

  • ref 属性获取 DOM 元素或组件实例的直接引用
  • 3.5+ 用 useTemplateRef(),之前用 ref(null)
  • 只能在挂载后访问,首次渲染是 null
  • 组件 ref 获取实例,<script setup> 默认私有,用 defineExpose 暴露
  • v-for 里的 ref 是数组
  • 函数 ref 提供完全的控制灵活性