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 响应式系统的优势。

相关推荐
Qrun13 小时前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp13 小时前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.14 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl16 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫17 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友17 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理19 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻19 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
mapbar_front20 小时前
在职场生存中如何做个不好惹的人
前端
牧杉-惊蛰20 小时前
纯flex布局来写瀑布流
前端·javascript·css