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

Vue3 模板引用实战:useTemplateRef 与 ref 的 3 种 DOM 操作模式

Vue3 模板引用实战:useTemplateRef 与 ref 的 3 种 DOM 操作模式

在 Vue3 的 Composition API 中,模板引用(Template Refs)是连接响应式数据与真实 DOM 的桥梁。本文将深入探讨如何利用useTemplateRef(Vue 3.5+)和传统ref实现三种典型场景的 DOM 操作,帮助开发者突破虚拟 DOM 的限制,直接与原生 DOM 交互。

1. 自动聚焦输入框:交互体验的起点

表单交互中,自动聚焦是提升用户体验的常见需求。传统实现需要手动调用focus(),而 Vue3 提供了更优雅的解决方案。

1.1 useTemplateRef 实现(推荐)

<script setup> import { useTemplateRef, onMounted } from 'vue' const inputRef = useTemplateRef('input-field') onMounted(() => { inputRef.value?.focus() }) </script> <template> <input ref="input-field" placeholder="自动获得焦点" /> </template>

关键点解析:

  • useTemplateRef的参数需与模板中的ref值严格匹配
  • TypeScript 会自动推断inputRef.value的类型为HTMLInputElement
  • ?.可选链操作符避免未挂载时的空值错误

1.2 传统 ref 实现

<script setup> import { ref, onMounted } from 'vue' const inputRef = ref<HTMLInputElement | null>(null) onMounted(() => { inputRef.value?.focus() }) </script> <template> <input ref="inputRef" /> </template>

对比分析:

特性useTemplateRef传统 ref
类型推断自动需手动声明
命名一致性强制匹配自由命名
版本要求Vue ≥3.5所有版本
模板 ref 值字符串变量引用

提示:在需要兼容旧版本或复杂命名场景下,传统 ref 更具灵活性;而在 Vue 3.5+ 项目中,useTemplateRef能提供更好的开发体验。

2. 集成第三方图表库:突破虚拟 DOM 的限制

当集成 ECharts、D3.js 等需要直接操作 DOM 的库时,模板引用成为必要手段。下面以 ECharts 为例:

2.1 基础集成模式

<script setup> import { useTemplateRef, onMounted, watch } from 'vue' import * as echarts from 'echarts' const chartRef = useTemplateRef('chart-container') let chartInstance: echarts.ECharts | null = null onMounted(() => { if (chartRef.value) { chartInstance = echarts.init(chartRef.value) renderChart() } }) function renderChart() { chartInstance?.setOption({ xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed'] }, yAxis: { type: 'value' }, series: [{ data: [120, 200, 150], type: 'bar' }] }) } </script> <template> <div ref="chart-container" style="width: 600px; height: 400px;"></div> </template>

2.2 响应式适配方案

当图表需要响应数据变化时:

const props = defineProps<{ data: number[] }>() watch(() => props.data, (newData) => { chartInstance?.setOption({ series: [{ data: newData }] }) }, { deep: true })

性能优化技巧:

  • 使用shallowRef避免不必要的深度响应
  • 通过ResizeObserver实现容器自适应
  • onUnmounted中调用dispose()释放资源
import { shallowRef, onUnmounted } from 'vue' const chartInstance = shallowRef<echarts.ECharts | null>(null) onUnmounted(() => { chartInstance.value?.dispose() })

3. 动态测量元素尺寸:响应式布局的核心

实现响应式布局常需要获取元素的实际尺寸。传统方案依赖全局事件,而 Vue3 的组合式 API 提供了更模块化的解决方案。

3.1 基础尺寸测量

<script setup> import { useTemplateRef, ref, onMounted } from 'vue' const containerRef = useTemplateRef('measurable') const dimensions = ref({ width: 0, height: 0 }) onMounted(() => { if (containerRef.value) { dimensions.value = { width: containerRef.value.offsetWidth, height: containerRef.value.offsetHeight } } }) </script> <template> <div ref="measurable" class="resizable-box"> 当前尺寸:{{ dimensions.width }} × {{ dimensions.height }} </div> </template>

3.2 响应式尺寸监听

通过组合式函数封装可复用的尺寸监听逻辑:

// useElementSize.ts import { ref, onMounted, onUnmounted } from 'vue' export function useElementSize(targetRef: Ref<HTMLElement | null>) { const width = ref(0) const height = ref(0) let observer: ResizeObserver | null = null onMounted(() => { if (targetRef.value) { observer = new ResizeObserver((entries) => { const entry = entries[0] width.value = entry.contentRect.width height.value = entry.contentRect.height }) observer.observe(targetRef.value) } }) onUnmounted(() => { observer?.disconnect() }) return { width, height } }

使用示例:

<script setup> import { useTemplateRef } from 'vue' import { useElementSize } from './useElementSize' const containerRef = useTemplateRef('responsive-container') const { width, height } = useElementSize(containerRef) </script> <template> <div ref="responsive-container"> 容器实时尺寸:{{ width }} × {{ height }} </div> </template>

4. 高级模式:ref 的函数式用法

Vue3 支持更灵活的函数式 ref,特别适合动态 ref 和组件库开发场景。

4.1 动态元素引用

<script setup> import { ref } from 'vue' const items = ref([1, 2, 3]) const itemRefs = ref<HTMLElement[]>([]) function setItemRef(el: HTMLElement | null, index: number) { if (el) itemRefs.value[index] = el } </script> <template> <div v-for="(item, index) in items" :key="item"> <div :ref="el => setItemRef(el, index)">Item {{ item }}</div> </div> </template>

4.2 组件方法暴露

子组件通过defineExpose暴露方法:

<!-- ChildComponent.vue --> <script setup> const sayHello = () => console.log('Hello from child!') defineExpose({ sayHello }) </script>

父组件通过 ref 调用:

<script setup> import { ref } from 'vue' import ChildComponent from './ChildComponent.vue' const childRef = ref<InstanceType<typeof ChildComponent>>() function triggerChild() { childRef.value?.sayHello() } </script> <template> <ChildComponent ref="childRef" /> <button @click="triggerChild">调用子组件方法</button> </template>

类型安全提示:

  • 使用InstanceType<typeof Component>获取组件实例类型
  • 通过defineExpose明确暴露的接口
  • 可选链操作符避免未定义错误

在实际项目中,合理选择模板引用模式能显著提升代码的可维护性。对于简单场景,useTemplateRef提供了开箱即用的便利;复杂场景下,组合式函数封装和函数式 ref 能带来更大的灵活性。

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

相关文章:

  • 微信同声传译插件 3大核心API对比:语音识别、翻译、合成性能实测
  • 2026年7月最新泰州欧米茄官方售后客户服务电话及线下网点地址 - 欧米茄官方服务中心
  • 2026年四川租桌椅企业选择指南:聚焦大型活动服务能力 - 品牌鉴赏官2026
  • USB 2.0 协议栈实战:从域、包到4种传输类型的完整数据流解析
  • 智能音频收藏管理:如何高效实现喜马拉雅VIP与付费专辑批量下载
  • 鸿蒙三方库 | harmony-utils之DeviceUtil振动控制详解
  • AI时代职场生存指南:从工具替代到人机协作的转型策略
  • clibcni未来发展方向:容器网络技术的7大演进趋势
  • 2026 年宜昌专业的冷却塔防腐涂料供应厂家哪家可靠,别让锈蚀吞噬你的设备:冷却塔的终极保护方案 - 行业推荐官【官方】
  • 兰州旧房翻新公司哪家靠谱?2026兰州家装设计施工/新房整装/别墅装修/全案整装公司精选推荐 - 栗子测评
  • PIC18LF2515驱动EPT-14A4005P蜂鸣器的智能警报系统设计
  • Linux LVM 快速扫描:pvscan 命令详解,一键检索系统物理卷
  • 基于AirSim+UE4搭建无人机视觉算法仿真环境:从零到实战避坑指南
  • 锂离子电池组单元平衡技术及BQ25887与STM32L496ZG应用
  • 用ChatGPT零基础学Python(真实项目级教学链路全拆解)
  • 如何用SRWE打破Windows窗口限制?游戏截图与多分辨率测试的终极解决方案
  • Palworld跨服务器数据迁移完整方案:深度解析GUID同步与角色修复实战指南
  • 【面试算法笔记】0102-数组-移除元素 相关
  • 直接插入排序 vs C++ STL sort:5个维度实测性能与适用场景对比
  • 2026瓷砖胶哪个牌子好?岩板/大板瓷砖胶十大品牌榜单 - 栗子测评
  • 千问新人福利,8元通用立减券,附专属福利口令,千问新用户专属220372
  • Vue 2 到 Vue 3 的语法演进:从 Options API 到 Composition API 完全指南
  • MATROX Y7469-03 采集卡
  • iOS激活锁绕过终极指南:Applera1n让被锁iPhone重获新生
  • 宝珀中国官方售后服务中心|服务电话与网点地址权威信息通知(2026年7月更新) - 宝珀官方售后服务中心
  • 如何用HS2汉化补丁一键解锁Honey Select 2完整中文体验
  • Microsoft 365遭大规模密码喷射攻击,逾78个账户沦陷
  • 深入解析Unreal模块生命周期:从加载到关闭的完整指南
  • Vue 3 Composition API 实战:从 Options API 迁移的工程策略
  • EC 4+2:1 亚节点纠删码实战:3节点6盘配置,硬盘故障容忍数提升至2