Vue 3.5 新特性:useTemplateRef 详解

更新日期: 2025-12-05 阅读: 31 标签: 特性

vue 3.5 带来了一个实用的新功能:useTemplateRef。这个 api 解决了之前模板引用的一些问题。我们来详细了解一下它的作用和用法。


以前的问题

在 Vue 3.0 到 3.4 版本中,使用模板引用时确实有些麻烦。

1. 命名必须完全一致

在模板中写 ref="inputField",在脚本中就必须用 const inputField = ref(null)。名字必须一模一样,改一个地方,另一个地方也要跟着改,容易出错。

2. 类型提示不完整

如果不特别指定类型,默认是 any 类型。这样编辑器就无法提供准确的代码提示,开发效率受影响。

3. 动态引用不好处理

在循环中使用动态引用比较麻烦。比如 :ref="'item-' + index" 这样的写法,在脚本中获取对应引用不太方便。

4. 逻辑复用困难

如果想在自定义函数中封装 ref 相关逻辑,需要预先知道变量名,这增加了代码的耦合度。


回顾以前的写法

先看看我们以前是怎么写的:

<template>
  <input ref="username" />
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'

// 变量名必须和模板中的 ref 值一样
const username = ref<htmlInputElement | null>(null)

onMounted(() => {
  username.value?.focus()
})
</script>

这种写法的问题很明显:模板和脚本通过变量名紧密绑定在一起。改名字要改两个地方,容易遗漏。

循环中的情况更复杂:

<template>
  <div v-for="(item, i) in list" :key="i">
    <input :ref="`input-${i}`" />
  </div>
</template>

对于这种情况,官方文档也不推荐在 <script setup> 中使用动态 ref,开发者需要自己想办法处理。


useTemplateRef 是什么?

Vue 3.5 引入的 useTemplateRef 函数,用法很简单:

function useTemplateRef<T = Element>(
  key: string
): Readonly<Ref<T | null>>

它接收一个字符串参数(就是模板中 ref 属性的值),返回一个只读的 ref 对象。最大的好处是:你可以在任何地方调用它,不再受变量名约束。


基本用法

看看具体怎么用:

<template>
  <input ref="username" />
</template>

<script setup lang="ts">
import { useTemplateRef, onMounted } from 'vue'

// 现在可以自由命名变量了
const myInput = useTemplateRef('username')

onMounted(() => {
  myInput.value?.focus() // 有完整的类型提示
})
</script>

模板中还是写 ref="username",但脚本中可以随意命名变量。编辑器也能正确识别元素类型,提供代码提示。


实际应用场景

1. 表单自动聚焦

以前的做法:

const username = ref<HTMLInputElement | null>(null)

现在的做法:

const username = useTemplateRef('username')

区别很明显:现在变量名可以自由选择,类型也能自动推断。

2. 处理动态列表

<template>
  <div v-for="(item, index) in items" :key="index">
    <input :ref="`input-${index}`" />
    <button @click="focusInput(index)">聚焦</button>
  </div>
</template>

<script setup lang="ts">
import { useTemplateRef } from 'vue'

const focusInput = (index: number) => {
  const el = useTemplateRef<HTMLInputElement>(`input-${index}`)
  el.value?.focus()
}
</script>

这种方式比原来简单很多。原来需要手动管理引用映射,现在直接按名字获取就行。

3. 封装复用逻辑

可以封装成独立的函数:

// hooks/useFocus.ts
import { useTemplateRef, nextTick } from 'vue'

export function useFocus(refKey: string) {
  const target = useTemplateRef<HTMLInputElement>(refKey)
  
  const focus = () => nextTick(() => target.value?.focus())
  
  return { focus }
}

在组件中使用:

<template>
  <input ref="email" />
  <button @click="focus">聚焦</button>
</template>

<script setup lang="ts">
import { useFocus } from '@/hooks/useFocus'

const { focus } = useFocus('email')
</script>

这样做的好处是逻辑和命名完全分离。封装函数时不需要知道组件内部的具体变量名。


性能考虑

你可能关心性能问题。Vue 3.5 在编译阶段会收集模板中的 ref 引用。useTemplateRef 实际上是从预先生成的队列中读取对应引用,不会触发额外的依赖收集,性能接近直接操作。


使用要求

要使用这个功能,需要满足:

  • Vue 版本 3.5.0 或更高(2024年9月发布)

  • 开发工具建议使用 Volar 2.1.0 或更高版本,以获得完整的类型提示

  • 这个 API 完全向后兼容,可以逐步替换,不会破坏现有代码


总结

useTemplateRef 解决了 Vue 模板引用中的几个实际问题。它让变量命名更自由,类型推断更准确,动态引用更简单,逻辑封装更方便。

这个新特性不会完全取代传统的 ref 写法。两种方式可以根据需要选择使用。对于简单的场景,传统写法可能更直接。对于需要解耦、复用或处理动态引用的场景,useTemplateRef 是更好的选择。

实际开发中,你可以根据具体情况选择合适的方法。两种写法可以共存,逐步迁移。这个改进让 Vue 的开发体验更好,代码也更清晰易维护。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/13292

CSS新特性contain,控制页面的重绘与重排

contain 属性允许我们指定特定的 DOM 元素和它的子元素,让它们能够独立于整个 DOM 树结构之外。目的是能够让浏览器有能力只对部分元素进行重绘、重排,而不必每次都针对整个页面。

Html5、Css3、ES6的新特性

Html5的新特性语义化标签:有利于SEO,有助于爬虫抓取更多的有效信息,爬虫是依赖于标签来确定上下文和各个关键字的权重。表单新特性,多媒体视频(video)和音频(audio)

ES6新特性--var、let、const

var不存在块级作用域,具有变量提升机制。 let和const存在块级作用域,不存在变量提升。在同一作用域内只能声明一次。const在声明时需要赋值且无法修改,但如果常量是对象,则对象的属性可以修改。

Js即将到来的3个新特性

Optional Chaining(可选链式调用);Nullish coalescing(空值合并);Pipeline operator(管道运算符)通过三个函数对字符串进行处理;

Angular 8的新特性介绍

在今天早些时候Angular团队发布了8.0.0稳定版。其实早在NgConf 2019大会上,演讲者就已经提及了从工具到差分加载的许多内容以及更多令人敬畏的功能。下面是我对8.0.0一些新功能的简单介绍,希望可以帮助大家快速了解新版本

使用 React 要懂的 Js特性

与我使用的其他框架相比,我最喜欢 React 的原因之一就是它对 JavaScript 的暴露程度。没有模板DSL( JSX 编译为合理的 JavaScript),组件 API 只是通过添加 React Hooks 变得更简单,并且该框架为解决的核心 UI 问题提供非常少的抽象概念

ES2019 新特性汇总

最近 ECMAScript2019,最新提案完成:tc39 Finished Proposals,我这里也是按照官方介绍的顺序进行整理,如有疑问,可以查看官方介绍啦~另外之前也整理了 《ES6/ES7/ES8/ES9系列》,可以一起看哈。

Js的用途和特性

JavaScript 最初的目的是为了“赋予网页生命”。这种编程语言我们称之为脚本。它们可以写在 HTML 中,在页面加载的时候会自动执行。脚本作为纯文本存在和执行。它们不需要特殊的准备或编译即可运行。

十个超级实用的 JS 特性

你可能刚上手 JavaScript,或者只是曾经偶尔用过。不管怎样,JavaScript 改变了很多,有些特性非常值得一用。 这篇文章介绍了一些特性,在我看来,一个严肃的 JavaScript 开发者每天都多多少少会用到这些特性

解密HTTP/2与HTTP/3 的新特性

HTTP/2 相比于 HTTP/1.1,可以说是大幅度提高了网页的性能,只需要升级到该协议就可以减少很多之前需要做的性能优化工作,当然兼容问题以及如何优雅降级应该是国内还不普遍使用的原因之一。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!