Vue3 模板引用实战:useTemplateRef 与 ref 的 3 种 DOM 操作模式 Vue3 模板引用实战useTemplateRef 与 ref 的 3 种 DOM 操作模式在 Vue3 的 Composition API 中模板引用Template Refs是连接响应式数据与真实 DOM 的桥梁。本文将深入探讨如何利用useTemplateRefVue 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 refinput-field placeholder自动获得焦点 / /template关键点解析useTemplateRef的参数需与模板中的ref值严格匹配TypeScript 会自动推断inputRef.value的类型为HTMLInputElement?.可选链操作符避免未挂载时的空值错误1.2 传统 ref 实现script setup import { ref, onMounted } from vue const inputRef refHTMLInputElement | null(null) onMounted(() { inputRef.value?.focus() }) /script template input refinputRef / /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 refchart-container stylewidth: 600px; height: 400px;/div /template2.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 shallowRefecharts.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 refmeasurable classresizable-box 当前尺寸{{ dimensions.width }} × {{ dimensions.height }} /div /template3.2 响应式尺寸监听通过组合式函数封装可复用的尺寸监听逻辑// useElementSize.ts import { ref, onMounted, onUnmounted } from vue export function useElementSize(targetRef: RefHTMLElement | 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 refresponsive-container 容器实时尺寸{{ width }} × {{ height }} /div /template4. 高级模式ref 的函数式用法Vue3 支持更灵活的函数式 ref特别适合动态 ref 和组件库开发场景。4.1 动态元素引用script setup import { ref } from vue const items ref([1, 2, 3]) const itemRefs refHTMLElement[]([]) function setItemRef(el: HTMLElement | null, index: number) { if (el) itemRefs.value[index] el } /script template div v-for(item, index) in items :keyitem div :refel setItemRef(el, index)Item {{ item }}/div /div /template4.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 refInstanceTypetypeof ChildComponent() function triggerChild() { childRef.value?.sayHello() } /script template ChildComponent refchildRef / button clicktriggerChild调用子组件方法/button /template类型安全提示使用InstanceTypetypeof Component获取组件实例类型通过defineExpose明确暴露的接口可选链操作符避免未定义错误在实际项目中合理选择模板引用模式能显著提升代码的可维护性。对于简单场景useTemplateRef提供了开箱即用的便利复杂场景下组合式函数封装和函数式 ref 能带来更大的灵活性。

相关新闻

最新新闻

vivo校招笔试经验:Java基础与操作系统高频考点全解析

vivo校招笔试经验:Java基础与操作系统高频考点全解析

2018年秋招那会儿,我刚从学校出来,投了一堆手机厂商的软件开发岗,vivo的笔试是让我印象比较深的一次。不是因为题目特别难,而是它的题型分布和考察思路很有代表性,基础题占大头,但每一道都在考“你到底有没…

2026/8/31 21:30:55
鸿蒙OS 应用配置文件详解:从 module.json5 到 app.json5 的完整实践

鸿蒙OS 应用配置文件详解:从 module.json5 到 app.json5 的完整实践

1. 引言在鸿蒙OS(HarmonyOS)应用开发中,配置文件是应用工程的“骨架”,它决定了应用如何被系统识别、如何申请权限、如何声明页面与组件。无论是初学者还是有一定经验的开发者,理解配置文件的结构与字段含义&#xff0…

2026/8/31 21:30:55
低成本机器人开发实战:从ROS2到Hugging Face生态

低成本机器人开发实战:从ROS2到Hugging Face生态

Hugging Face 推出一款 399 美元的 Microduck 机器人时,很多人的第一反应是“这个价钱能买到什么?”作为一家以模型和数据集闻名的人工智能公司,Hugging Face 进入机器人硬件领域,真正的看点其实不是那台机器人本身,而…

2026/8/31 21:30:55
物理信息神经网络(PINN)框架选型:PyTorch与TensorFlow实战对比

物理信息神经网络(PINN)框架选型:PyTorch与TensorFlow实战对比

刚开始接触 PINN(物理信息神经网络)的时候,几乎每个人都会卡在同一个问题前:网上的教程一会儿用 PyTorch,一会儿用 TensorFlow,到底该学哪个?我自己在给这个入门系列准备代码时,也经…

2026/8/31 21:30:55
DeepSeek Harness 实战:本地部署、批量评测与 API 集成指南

DeepSeek Harness 实战:本地部署、批量评测与 API 集成指南

DeepSeek 模型本身能力再强,真正让开发者在本地卡住的,往往不是模型文件,而是围绕模型形成的那套工作流怎么装、怎么调、怎么批量跑。最近社区里把注意力放在 DeepSeek Harness 上,核心不是再发一个新模型,而是把 Deep…

2026/8/31 21:30:55
微信小程序酒类商城模板源码解析:从解压到上线避坑指南

微信小程序酒类商城模板源码解析:从解压到上线避坑指南

简介:这是一套专为酒类电商场景设计的微信小程序源码模板,面向前端开发者及小程序初学者,解决从零搭建专业酒类商城效率低、功能模块复用难的问题。资源共190个文件,涵盖38个JS逻辑文件(含app.js、request.js、orderWi…

2026/8/31 21:25:55