普通视图

发现新文章,点击刷新页面。
昨天 — 2026年1月23日首页

useTemplateRef和ref的区别

作者 Hone
2026年1月23日 16:39

useTemplateRefref 都是用来创建响应式引用(Reactive References)的,但在 Vue 3.5+ 中,useTemplateRef 是一个专门为模板引用(Template Refs)设计的组合式 API (Composable) 。让我们详细对比一下它们:

ref

  • 核心功能: ref 是 Vue 最基础的响应式系统 API 之一。它可以包装任何值(原始类型、对象、DOM 元素、组件实例等),使其成为响应式的。

  • 用途广泛:

    • 存储和响应式地更新本地组件状态(如 count = ref(0))。
    • 作为模板引用(虽然在 3.5+ 之前常用)。
    • 在任何需要响应式引用的地方。
  • 在模板引用中的用法 (旧方式) :

    <template>
      <div ref="divRef">Hello World</div>
    </template>
    
    <script setup>
    import { ref, onMounted } from 'vue';
    
    const divRef = ref(null); // 创建一个 ref
    
    onMounted(() => {
      // divRef.value 现在是 DOM 元素
      console.log(divRef.value); // <div>Hello World</div>
      divRef.value.focus(); // 例如,聚焦到元素上
    });
    </script>
    
    • 问题: 在 <script setup> 中,divRef 会暴露给模板,即使你只想在脚本内部使用它。这可能会污染模板的上下文。

useTemplateRef (Vue 3.5+)

  • 核心功能: 专门用于获取对模板中元素或组件的引用。它返回一个getter 函数,而不是一个 ref 对象。

  • 目的: 解决 ref 作为模板引用时暴露到模板上下文的问题,提供更清晰、更符合直觉的 API。

  • 用途: 用于模板引用。

  • 返回值: 一个 getter 函数,调用它会返回最新的模板引用值。这个函数本身是响应式的,但其返回值(即引用的元素或组件实例)不是。

  • 优势:

    • 不污染模板上下文: useTemplateRef 返回的 getter 不会被自动暴露到模板中,保持了模板上下文的整洁。
    • 意图明确: 使用 useTemplateRef 明确表示你正在创建一个模板引用,提高了代码的可读性。
    • 类型推断: 在 TypeScript 中,useTemplateRef 能提供更精确的类型推断。
  • 在模板引用中的用法 (新方式) :

    <template>
      <div ref="divRef">Hello World</div>
    </template>
    
    <script setup>
    import { useTemplateRef, onMounted } from 'vue';
    
    // useTemplateRef 返回一个 getter 函数
    const getDivRef = useTemplateRef('divRef');
    
    onMounted(() => {
      // 调用 getter 函数获取 DOM 元素
      console.log(getDivRef()); // <div>Hello World</div>
      getDivRef()?.focus(); // 例如,聚焦到元素上
    });
    </script>
    
    • 注意:在 ref 指令中使用的字符串(如 'divRef')必须与 useTemplateRef 的参数完全匹配。
    • getDivRef() 返回的是实际的 DOM 元素或组件实例,如果元素未挂载,则可能返回 nullundefined

对比总结

特性 ref useTemplateRef
主要目的 创建通用的响应式引用 专门用于模板引用
返回值 一个包含 .value 属性的 ref 对象 一个 getter 函数
模板暴露 会暴露到模板上下文(如果在 <script setup> 中定义) 不会暴露到模板上下文
类型推断 一般 更好(尤其是在 TS 中)
意图表达 通用,需看上下文 明确
Vue 版本要求 3.0+ 3.5+
何时使用 通用响应式状态、旧项目中的模板引用 Vue 3.5+ 项目中的模板引用 (推荐)

结论

  • 对于模板引用(获取 DOM 元素或子组件实例),强烈推荐在 Vue 3.5+ 项目中使用 useTemplateRef。它更清晰、更安全、类型更友好。
  • 对于通用的响应式状态管理(如计数器、布尔标志等),继续使用 ref
  • 在你的项目中,如果已经升级到了 Vue 3.5 或更高版本,并且需要获取模板引用,请优先考虑 useTemplateRef
❌
❌