Vue 3 模板引用(Template Refs)详解与实战示例

Vue 3 模板引用(Template Refs)详解与实战示例

引言

在 Vue 开发中,通常推荐使用 响应式数据 (refreactive) 进行数据绑定,而不是直接操作 DOM。但是,在某些情况下,我们确实需要访问某个组件或 DOM 元素,这时候就可以使用 模板引用(Template Refs)

本篇文章将详细介绍 Vue 3 的 ref 模板引用的用法、适用场景,并通过多个示例展示如何在 Vue 组件中高效操作 DOM 和组件实例。


1. 什么是 Vue 模板引用?

模板引用(Template Refs) 允许我们在 Vue 组件的模板中标记一个 DOM 元素或子组件,并在 setup 选项中访问它。

基本语法

html 复制代码
<template>
  <div ref="myDiv">Hello Vue!</div>
</template>

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

const myDiv = ref(null); // 定义模板引用

onMounted(() => {
  console.log(myDiv.value); // 获取 DOM 元素
});
</script>

说明

  • ref="myDiv" 绑定到 myDiv 变量
  • onMounted 钩子确保 myDiv.value 在 DOM 渲染完成后可用

2. 模板引用的使用场景

✅ 操作原生 DOM

当我们需要手动操作 DOM 时,如获取元素的宽高、设置焦点等:

html 复制代码
<template>
  <input ref="inputRef" type="text" placeholder="输入内容">
  <button @click="focusInput">聚焦输入框</button>
</template>

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

const inputRef = ref(null);

const focusInput = () => {
  inputRef.value.focus(); // 手动聚焦输入框
};
</script>

✅ 获取子组件实例

可以使用 ref 访问子组件的方法和数据:

html 复制代码
<!-- 子组件 (Child.vue) -->
<template>
  <div>子组件</div>
</template>

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

const message = ref("Hello from Child Component!");

const sayHello = () => {
  console.log(message.value);
};

defineExpose({ sayHello }); // 允许父组件访问 `sayHello`
</script>
html 复制代码
<!-- 父组件 -->
<template>
  <Child ref="childRef" />
  <button @click="callChildMethod">调用子组件方法</button>
</template>

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

const childRef = ref(null);

onMounted(() => {
  console.log(childRef.value); // 获取子组件实例
});

const callChildMethod = () => {
  childRef.value.sayHello(); // 调用子组件方法
};
</script>

defineExpose :Vue 3 需要使用 defineExpose 公开组件方法,否则父组件无法访问。


3. 使用 ref 访问多个元素

当我们需要访问 多个 DOM 元素时,可以使用 ref 结合 v-for

html 复制代码
<template>
  <div v-for="(item, index) in list" :key="index" ref="itemRefs">
    {{ item }}
  </div>
  <button @click="logElements">查看所有元素</button>
</template>

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

const list = ref(["Vue", "React", "Angular"]);
const itemRefs = ref([]); // 存储多个 DOM 元素

onMounted(() => {
  console.log(itemRefs.value); // 所有 div 的 DOM 元素
});

const logElements = () => {
  itemRefs.value.forEach(el => console.log(el.textContent));
};
</script>

注意ref 数组会在 onMounted 之后才填充值。


4. 访问 setup() 之外的数据

如果你在 setup() 之外使用 ref,可以通过 getCurrentInstance() 获取 Vue 实例:

html 复制代码
<script setup>
import { getCurrentInstance, onMounted } from 'vue';

onMounted(() => {
  const instance = getCurrentInstance();
  console.log(instance.refs); // 访问 ref
});
</script>

5. 结论

Vue 3 的 模板引用(Template Refs) 让我们可以更方便地访问 DOM 和子组件实例,适用于:

  • 操作原生 DOM(如获取焦点、测量元素尺寸)
  • 调用子组件方法 (通过 refdefineExpose
  • 获取多个元素 (使用 ref 数组)

但是 ,如果能用 Vue 的 响应式数据 来实现同样的效果,最好避免直接操作 DOM,以保持 Vue 响应式系统的优势。

相关推荐
树叶会结冰18 分钟前
HTML语义化:当网页会说话
前端·html
冰万森23 分钟前
解决 React 项目初始化(npx create-react-app)速度慢的 7 个实用方案
前端·react.js·前端框架
牧羊人_myr36 分钟前
Ajax 技术详解
前端
浩男孩1 小时前
🍀封装个 Button 组件,使用 vitest 来测试一下
前端
蓝银草同学1 小时前
阿里 Iconfont 项目丢失?手把手教你将已引用的 SVG 图标下载到本地
前端·icon
布列瑟农的星空1 小时前
重学React —— React事件机制 vs 浏览器事件机制
前端
程序定小飞1 小时前
基于springboot的在线商城系统设计与开发
java·数据库·vue.js·spring boot·后端
一小池勺1 小时前
CommonJS
前端·面试
孙牛牛2 小时前
实战分享:一招解决嵌套依赖版本失控问题,以 undici 为例
前端