当前位置:首页 > 文章列表 > 文章 > 前端 > Vue useTemplateRef 怎样获得模板引用类型

Vue useTemplateRef 怎样获得模板引用类型

来源:17golang原创 2026-11-07 00:18:47 0浏览 收藏

如果你在 Vue 里写过模板引用,通常会遇到两个问题:useTemplateRef() 拿到的到底是什么类型,以及为什么模板已经写了 ref,IDE 仍然提示可能是 null。结论是:Vue 3.5 及以上,静态 SFC 模板引用可以结合 Vue 的语言工具自动推断;推断覆盖不到的动态组件、非 SFC 或复杂类型,则应该显式传入泛型。

官方地址:https://vuejs.org/guide/essentials/template-refs.html

本文只围绕一个小场景展开:让一个搜索输入框、一个子组件和一个动态组件的模板引用获得可靠类型,并处理它们在挂载前或被 v-if 移除后的空值。

先把模板 ref 名称和 useTemplateRef 对齐

useTemplateRef() 的第一个参数不是随便起的变量说明,而是模板中 ref 属性的字符串值。两边对不上时,Vue 语言工具没有稳定的匹配入口,后续自然也无法根据目标元素推断类型。

这里有两个名字:脚本里的变量叫 searchBox,模板里的引用键也叫 searchBox。变量名可以不同,但字符串键必须和模板 ref 值相同。真正参与匹配的是后者。

Vue 3.5 的静态模板引用为什么能自动推断

当模板引用是静态写法时,Vue 3.5 配合 @vue/language-tools 2.1 可以根据匹配到的元素推断引用类型。对一个普通 来说,开发工具能够把 searchBox.value 识别为对应的输入元素接口,而不是让你手工写一长串 DOM 类型。

Vue useTemplateRef 从模板 ref 名称推断 HTMLInputElement 的静态结构说明图
图1:结构图展示静态模板引用从 ref 名称到 HTMLInputElement 的类型关系;这是原创说明图,不是 IDE 截图或运行证据。

这里的关键不是把 useTemplateRef 当作普通状态容器,而是让模板里的静态目标参与类型推断。vue-tsc 和 IDE 的提示来自这层关联,所以重命名时要同步修改模板键与脚本参数。

自动推断覆盖不到时,显式泛型怎么写

动态组件、非 SFC 用法或工具无法取得完整模板信息时,可以直接给出泛型。原生元素最简单:把目标 DOM 接口写在 useTemplateRef() 中。

import { useTemplateRef } from 'vue'

// 动态或无法自动推断时,显式指定原生元素接口
const searchBox = useTemplateRef('searchBox')

// 使用前仍要处理尚未挂载的 null
function clearSearch() {
  searchBox.value?.select()
  searchBox.value && (searchBox.value.value = '')
}

显式泛型解决的是“它是什么类型”,并不改变“它什么时候存在”。模板引用在组件挂载前可能为空,引用元素被 v-if 移除后也可能重新变成 null,所以可选链或类型守卫仍然需要保留。

子组件引用要区分实例类型和公开接口

把 ref 放到子组件上时,引用目标不再是原生 DOM,而是子组件实例。对于静态导入的普通组件,可以用 InstanceType 得到实例类型,再交给 useTemplateRef。

如果子组件使用 ,它默认是私有的。父组件只有在子组件通过 defineExpose 暴露方法或状态后,才能通过模板引用访问这些成员。

如果只关心所有组件都共有的公开成员,可以使用 Vue 提供的 ComponentPublicInstance。它比具体组件类型宽,但更适合动态组件或不需要访问私有实现细节的场景。

动态组件和 v-for:类型边界要写清楚

动态组件可能在多个组件类型之间切换,不能假设引用永远是某一个具体实例。可以把候选实例组成联合类型;若只需要共同能力,则退回到 ComponentPublicInstance。

import { useTemplateRef } from 'vue'
import type { ComponentPublicInstance } from 'vue'
import Foo from './Foo.vue'
import Bar from './Bar.vue'

type FooType = InstanceType
type BarType = InstanceType

// 动态组件的引用类型覆盖两个可能的实例
const componentRef = useTemplateRef('component')

// 只依赖公共实例能力时使用更宽的类型
const publicRef = useTemplateRef('publicComponent')
Vue useTemplateRef 显式泛型、组件实例和 null 生命周期边界说明图
图2:关系图对比原生元素泛型、组件实例类型与 null 生命周期边界;这是原创说明图,不是运行截图。

在 v-for 中,Vue 3.5 也支持把同一个模板引用收集为数组。此时需要把它理解为“一组匹配元素”,不要依赖数组顺序和源数组永久一致;如果业务需要稳定对应关系,应该自己使用更明确的键或数据结构。

Vue 3.5 之前的兼容写法

useTemplateRef() 是 Vue 3.5 引入的辅助函数。更早的版本要用普通 ref 保存模板引用,并显式把初始值写成 null。如果项目还没有升级到 3.5,不能只复制新 API。

两种写法的生命周期事实相同:引用并不是创建时就指向 DOM。升级时可以先保留 null 判断,再把声明换成 useTemplateRef,最后让 IDE 或 vue-tsc 接管静态元素的推断。

一张表记住选择方式

场景推荐写法注意点
Vue 3.5+ 静态原生元素useTemplateRef('input')模板 ref 键要完全匹配,类型可由语言工具推断
无法自动推断的原生元素useTemplateRef('input')泛型只解决类型,仍要处理 null
静态导入子组件InstanceType 子组件需用 defineExpose 暴露成员
动态组件或只需公共能力ComponentPublicInstance类型更宽,只访问各组件共有的公开成员
Vue 3.5 之前ref(null)使用普通 ref,并保持挂载生命周期判断

最后检查这三个容易混淆的点

第一,useTemplateRef 的参数是模板中的引用键,不是 TypeScript 变量名;第二,自动推断依赖静态 SFC 模板与匹配的 Vue 语言工具,动态场景要准备显式泛型;第三,类型正确不等于运行时已经挂载,onMounted、v-if 和组件卸载都会让引用经历 null 状态。

把这三点分开后,模板引用的写法就比较稳定:能推断时让工具推断,不能推断时明确写出目标类型,访问任何引用时都保留生命周期边界。

相关问题

useTemplateRef 一定要在 onMounted 里使用吗?

不一定要把声明放进 onMounted,但读取 DOM 或子组件实例通常要等挂载后,并且仍需处理卸载后的 null。

为什么 useTemplateRef 的 value 还是可能为 null?

模板引用在首次渲染前还没有对应节点,使用 v-if 移除节点后也会失去引用,所以严格类型检查会要求可选链或类型守卫。

子组件 ref 为什么拿不到 script setup 里的方法?

组件默认只暴露公开接口,需要在子组件中用 defineExpose 显式暴露,并在父组件中使用对应实例类型。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Vite css.lightningcss 怎样切换 CSS 压缩器Vite css.lightningcss 怎样切换 CSS 压缩器
上一篇
Vite css.lightningcss 怎样切换 CSS 压缩器
Vue defineModel 怎样处理带默认值的绑定
下一篇
Vue defineModel 怎样处理带默认值的绑定
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    918次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    923次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    1020次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    1000次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    823次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码