news 2026/4/17 20:12:32

Vue ref 使用学习笔记

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue ref 使用学习笔记

1. 什么是 ref

ref是 Vue 中的一个特殊 attribute,用于给元素或子组件注册引用信息。引用信息会被注册在父组件的$refs对象上。

核心作用

  • DOM 元素访问:在普通 DOM 元素上使用时,引用指向 DOM 元素本身
  • 组件实例访问:在子组件上使用时,引用指向组件的实例

重要特性

  • ref是作为渲染结果被创建的,在初始渲染时不能访问(此时还不存在)
  • $refs不是响应式的,不应该在模板中做数据绑定
  • 在使用v-for时,引用会是一个包含 DOM 节点或组件实例的数组

2. 基本用法

2.1 在组合式 API 中使用(Vue 3.5+)

使用useTemplateRef()辅助函数:

<script setup> import { useTemplateRef, onMounted } from 'vue' // 第一个参数必须与模板中的 ref 值匹配 const input = useTemplateRef('my-input') onMounted(() => { input.value.focus() }) </script> <template> <input ref="my-input" /> </template>

2.2 在组合式 API 中使用(Vue 3.5 前)

<script setup> import { ref, onMounted } from 'vue' // 声明一个 ref 来存放该元素的引用 // 必须和模板里的 ref 同名 const input = ref(null) onMounted(() => { input.value.focus() }) </script> <template> <input ref="input" /> </template>

2.3 在选项式 API 中使用

<script> export default { mounted() { this.$refs.input.focus() } } </script> <template> <input ref="input" /> </template>

3. 具体应用场景

3.1 操作 DOM 元素

场景:在组件挂载后自动聚焦到输入框

<script setup> import { ref, onMounted } from 'vue' const inputRef = ref(null) onMounted(() => { inputRef.value.focus() }) </script> <template> <input ref="inputRef" placeholder="请输入内容" /> </template>

3.2 访问子组件实例

场景:父组件调用子组件的方法

<!-- Child.vue --> <script setup> import { ref } from 'vue' const count = ref(0) const increment = () => { count.value++ } // 暴露方法给父组件 defineExpose({ increment, count }) </script> <template> <div>子组件计数:{{ count }}</div> </template>
<!-- Parent.vue --> <script setup> import { ref, onMounted } from 'vue' import Child from './Child.vue' const childRef = ref(null) onMounted(() => { // 调用子组件的方法 childRef.value.increment() console.log('子组件计数:', childRef.value.count) }) </script> <template> <Child ref="childRef" /> </template>

3.3 处理 v-for 中的引用

场景:获取一组 DOM 元素或组件实例

<script setup> import { ref, onMounted } from 'vue' const itemRefs = ref([]) onMounted(() => { // itemRefs.value 是一个包含所有 li 元素的数组 console.log(itemRefs.value.length) // 访问第一个元素 if (itemRefs.value[0]) { itemRefs.value[0].style.color = 'red' } }) </script> <template> <ul> <li v-for="item in 5" :key="item" ref="itemRefs"> 项目 {{ item }} </li> </ul> </template>

4. 注意事项

4.1 引用的生命周期

  • 挂载前ref值为null
  • 挂载后ref值为 DOM 元素或组件实例
  • 卸载后ref值为null(例如通过v-if控制)

4.2 响应式处理

如果需要监听引用的变化,应考虑到其值为null的情况:

<script setup> import { ref, watchEffect } from 'vue' const inputRef = ref(null) watchEffect(() => { if (inputRef.value) { inputRef.value.focus() } else { // 元素未挂载或已卸载 console.log('元素未就绪') } }) </script>

4.3 组件暴露控制

  • 使用<script setup>的组件:默认是私有的,需要通过defineExpose显式暴露属性和方法
  • 使用选项式 API 的组件:可以通过expose选项限制可访问的属性和方法
// 选项式 API 中限制暴露 export default { expose: ['publicData', 'publicMethod'], data() { return { publicData: 'foo', privateData: 'bar' } }, methods: { publicMethod() { /* ... */ }, privateMethod() { /* ... */ } } }

5. 类型标注(TypeScript)

5.1 为 DOM 元素标注类型

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

5.2 为组件标注类型

<script setup lang="ts"> import { ref, onMounted } from 'vue' import Child from './Child.vue' const childRef = ref<InstanceType<typeof Child> | null>(null) onMounted(() => { childRef.value?.increment() }) </script>

6. 最佳实践

  1. 优先使用 props 和 emit:大多数情况下,应该使用标准的 props 和 emit 接口来实现父子组件交互
  2. 仅在必要时使用 ref:ref 会创建父子组件之间的紧密耦合,应谨慎使用
  3. 避免在模板中使用 $refs:$refs 不是响应式的,不适合在模板中进行数据绑定
  4. 合理处理 null 值:在访问 ref 的值时,始终考虑其可能为 null 的情况
  5. 使用 TypeScript 类型标注:提高代码的可维护性和类型安全性

7. 常见问题与解决方案

7.1 问题:ref 值为 undefined

原因:在组件初始渲染时访问 ref,此时元素还未挂载

解决方案:在onMounted生命周期钩子中访问 ref,或使用watchEffect监听 ref 的变化

7.2 问题:v-for 中 ref 不是数组

原因:在某些 Vue 版本中,v-for 中的 ref 需要特殊处理

解决方案:使用函数式 ref 或确保正确的 ref 赋值方式

<template> <ul> <li v-for="item in 5" :key="item" :ref="el => el && itemRefs.push(el)"> 项目 {{ item }} </li> </ul> </template>

7.3 问题:无法访问子组件的方法

原因:子组件使用了<script setup>但未通过defineExpose暴露方法

解决方案:在子组件中使用defineExpose显式暴露需要访问的属性和方法

8. 总结

ref是 Vue 中用于直接访问 DOM 元素和组件实例的强大工具,合理使用可以简化某些场景下的开发工作。但需要注意其使用时机和最佳实践,避免过度依赖导致代码耦合度增加。

通过本文的学习,你应该掌握了:

  • ref的基本概念和作用
  • 在不同 API 风格中的使用方法
  • 各种应用场景的具体实现
  • 注意事项和最佳实践
  • 常见问题的解决方案
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 20:10:20

ADB图形化工具实测:一键解锁Bootloader/刷Recocovery到底靠不靠谱?

ADB图形化工具深度测评&#xff1a;解锁Bootloader与刷机实战指南 在安卓设备深度定制领域&#xff0c;图形化工具的出现极大降低了技术门槛。但面对Bootloader解锁、Recovery刷写这类高风险操作&#xff0c;工具的安全性和可靠性始终是用户最关心的问题。本文将基于多品牌实测…

作者头像 李华
网站建设 2026/4/17 20:10:12

企业级行为验证码技术方案深度解析与实战指南

前言在数字化业务高速发展的今天&#xff0c;恶意注册、撞库攻击、薅羊毛、刷票刷量等黑灰产行为已成为企业业务安全的重大威胁。传统字符验证码因OCR技术成熟和自动化脚本的普及&#xff0c;防护能力已显著下降。据行业数据显示&#xff0c;传统图形验证码的AI破解率已超过98%…

作者头像 李华
网站建设 2026/4/17 20:07:21

2026 网络安全自学路线:超详细从入门到精通,学完直接就业!

随着数字化转型加速与网络威胁常态化&#xff0c;网络安全已成为数字经济的 “安全底座”。2026 年行业数据显示&#xff0c;全球网络安全人才缺口超 300 万&#xff0c;国内缺口达数百万&#xff0c;平均起薪较 IT 行业高出 20%-30% &#xff0c;且呈现 “越老越值钱” 的职业…

作者头像 李华