当前位置: 首页 > news >正文

Vue 3 模板引用 (Template Refs)

概念

模板引用是 Vue 3 中直接访问 DOM 元素或组件实例的方式。通过特殊的 ref 属性,可以在 JavaScript 中获取对模板中元素的直接引用。

基本用法

1. 创建和使用 ref

<template><div><!-- 在元素上使用 ref --><input ref="inputRef" type="text" /><button @click="focusInput">聚焦输入框</button></div>
</template><script setup>
import { ref, onMounted } from 'vue'// 创建 ref,名称需要与模板中的 ref 属性值一致
const inputRef = ref(null)const focusInput = () => {// 访问 DOM 元素
  inputRef.value.focus()
}onMounted(() => {// 组件挂载后,ref 才会被赋值console.log(inputRef.value) // <input type="text">
})
</script>

2. 在选项式 API 中使用

<template><div ref="divRef">这是一个 div 元素</div>
</template><script>
export default {mounted() {// 通过 this.$refs 访问console.log(this.$refs.divRef) // <div>这是一个 div 元素</div>
  }
}
</script>

引用组件实例

1. 引用子组件

<!-- 父组件 -->
<template><div><ChildComponent ref="childRef" /><button @click="callChildMethod">调用子组件方法</button></div>
</template><script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'const childRef = ref(null)const callChildMethod = () => {// 调用子组件的方法
  childRef.value.someMethod()// 访问子组件的属性
  console.log(childRef.value.someProperty)
}
</script><!-- 子组件 ChildComponent.vue -->
<script setup>
import { ref, defineExpose } from 'vue'const someProperty = ref('子组件数据')const someMethod = () => {console.log('子组件方法被调用')
}// 需要显式暴露,父组件才能访问
defineExpose({someProperty,someMethod
})
</script>

动态 ref

<template><div v-for="item in items" :key="item.id"><!-- 动态 ref --><div :ref="el => { if (el) divRefs[item.id] = el }">{{ item.name }}</div></div>
</template><script setup>
import { ref, reactive } from 'vue'const items = ref([{ id: 1, name: 'Item 1' },{ id: 2, name: 'Item 2' }
])// 使用对象或 Map 存储多个 ref
const divRefs = reactive({})
</script>

ref 函数

<template><div><!-- 使用函数形式的 ref --><input :ref="setInputRef" type="text" /></div>
</template><script setup>
import { ref, onBeforeUpdate, onUpdated } from 'vue'let inputElement = nullconst setInputRef = (el) => {inputElement = el
}onBeforeUpdate(() => {// 在更新前清除 refinputElement = null
})onUpdated(() => {// 更新后重新设置 ref
  console.log(inputElement)
})
</script>

组合式 API 中的使用模式

1. 使用 ref 数组

<template><div><div v-for="i in 3" :key="i" :ref="el => { if (el) elementRefs[i-1] = el }">元素 {{ i }}</div></div>
</template><script setup>
import { ref, onMounted } from 'vue'const elementRefs = ref([])onMounted(() => {console.log(elementRefs.value) // [div, div, div]
})
</script>

2. ref 在响应式对象中

<script setup>
import { reactive, onMounted } from 'vue'const state = reactive({inputRef: null
})onMounted(() => {// 访问 reactive 对象中的 refif (state.inputRef) {state.inputRef.focus()}
})
</script><template><input ref="el => state.inputRef = el" type="text" />
</template>

最佳实践

  1. 访问时机:ref 在组件挂载后才可用,使用 onMounted 生命周期钩子确保安全访问

  2. 响应式:ref 本身是响应式的,但 ref 指向的 DOM 元素不是响应式的

  3. 类型安全:在 TypeScript 中为 ref 提供类型注解

// TypeScript 示例
import { ref } from 'vue'// HTML 元素 ref
const inputRef = ref<HTMLInputElement | null>(null)// 组件 ref(假设子组件有特定类型)
const childRef = ref<InstanceType<typeof ChildComponent> | null>(null)

避免过度使用:优先使用 Vue 的声明式数据驱动,必要时才使用 ref

常见应用场景

  • 聚焦输入框

  • 触发动画

  • 集成第三方 DOM 库

  • 测量元素尺寸

  • 手动触发组件方法

  • 文件上传控件

<template><div><!-- 文件上传示例 --><input ref="fileInput" type="file" style="display: none" @change="handleFileChange"/><button @click="triggerFileInput">选择文件</button></div>
</template><script setup>
import { ref } from 'vue'const fileInput = ref(null)const triggerFileInput = () => {fileInput.value.click()
}const handleFileChange = (event) => {const file = event.target.files[0]// 处理文件
}
</script>

模板引用提供了直接操作 DOM 的能力,但在 Vue 应用中应谨慎使用,优先考虑声明式的数据驱动方式

http://www.jsqmd.com/news/366152/

相关文章:

  • nt!IopSetupArbiterAndTranslators函数分析之对ResourceTranslator的处理生成translatorEntry
  • 机器人学习数据集构建实战指南:从架构设计到行业落地
  • 效率革命:FancyZones多屏协同的窗口管理技巧
  • 如何为不同规模选婚礼策划?2026年北京婚礼策划公司全面评测与推荐,直击定制与预算痛点 - 十大品牌推荐
  • 世界模型到底比大语言模型强在哪里?用一个小游戏项目说清楚
  • 2026!深圳新房艺术漆涂装房屋局改专业服务商权威推荐 文小墙居首成优选 - 品牌评测官
  • 高清图像煤矿传送带异物传输带上煤矿异物检测数据集VOC+YOLO格式784张1类别
  • 如何解锁Unity全功能?3个专业工具推荐与开发资源整合
  • 2026年北京婚礼策划公司推荐:基于行业认证与案例评价,直击品质与个性化核心痛点 - 十大品牌推荐
  • 2026国内企服平台推荐:赋能企业高质量发展的实用选择 - 品牌排行榜
  • smartmontools 7.5技术架构革新:从被动监测到主动预测的存储健康管理新范式
  • 模拟器构建实战指南:从环境搭建到性能优化的PCSX2全流程解析
  • DeepSeek-VL2模型定制化实战入门:从零开始打造专属视觉语言AI助手
  • 4个科学指南:如何通过TeslaMate实现电动车电池维护与续航优化
  • Claude Code终端编码助手安装配置指南
  • 2026年西安、咸阳等地口碑好的蛋糕西点培训学校推荐,专业培训全解析 - 工业设备
  • 【解决方案】跨设备加密相册:端到端加密的多平台数据同步方案
  • 2026四川房屋加固公司哪家好:房屋、桥梁、地基与裂缝修复哪家强 - 深度智识库
  • 颠覆式VRChat社交管理工具全攻略:重新定义虚拟社交体验
  • 气动冲片机
  • 2026年波波知了有什么服务?企业综合服务平台功能解析 - 品牌排行榜
  • 简单理解:非阻塞读取有哪些方法?
  • 3步掌握SharpShell开发:面向Windows扩展开发者的实践指南
  • Java小白求职互联网大厂:从Spring Boot到分布式缓存的面试场景
  • 工作流引擎集成实战指南:从BPMN前端开发到Camunda/Flowable全栈突破
  • 2026年有哪些值得关注的半导体展会?国内及国际知名展会推荐 - 品牌2025
  • 全网京东e卡回收权威合规平台有哪些 - 淘淘收小程序
  • 2026更新版!8个降AI率平台测评:研究生降AI率必备工具推荐
  • 2026年阿里云企业邮箱服务商推荐与选型指南 - 品牌2025
  • 2026年智能试剂出入库管理柜头部企业深度解析:技术实力与市场占有率双领先品牌盘点 - 品牌推荐大师