当前位置: 首页 > news >正文

Vue3 中的 ref、模板引用和 defineExpose 详解

一、ref 基础

在 Vue3 中,ref 是一个非常重要的响应式 API,它用于创建一个响应式的引用。

1.1 ref 的基本用法

javascript

import { ref } from 'vue';const count = ref(0); // 创建一个响应式引用,初始值为0console.log(count.value); // 访问值需要使用 .value
count.value++; // 修改值

特点:

  • ref 可以包装任何类型的值,使其变成响应式

  • 在 JavaScript 中访问或修改值时需要使用 .value

  • 在模板中使用时不需要 .value,Vue 会自动解包

1.2 为什么需要 ref

Vue3 使用 Proxy 实现响应式,但 Proxy 无法直接代理原始值(如 number, string 等)。ref 通过将这些值包装在一个对象中,解决了这个问题。

二、模板引用

模板引用是指直接在模板中访问 DOM 元素或组件实例的能力。

2.1 基本模板引用

html

<template><input ref="inputRef" type="text" />
</template><script setup>
import { ref, onMounted } from 'vue';const inputRef = ref(null); // 必须与模板中的 ref 同名onMounted(() => {inputRef.value.focus(); // 在挂载后自动聚焦
});
</script>

要点:

  1. 声明一个与模板中 ref 同名的响应式引用

  2. 在组件挂载后,inputRef.value 将指向 DOM 元素

  3. 只能在组件挂载后访问 ref 的值

2.2 在 v-for 中使用模板引用

html

<template><ul><li v-for="item in list" :key="item.id" ref="itemRefs">{{ item.text }}</li></ul>
</template><script setup>
import { ref, onMounted } from 'vue';const list = ref([{ id: 1, text: 'Item 1' },{ id: 2, text: 'Item 2' }
]);const itemRefs = ref([]);onMounted(() => {console.log(itemRefs.value); // 包含所有 li 元素的数组
});
</script>

注意: 在 v-for 中使用 ref 时,ref 的值将是一个包含所有元素的数组。

三、组件引用与 defineExpose

3.1 引用子组件

html

<!-- Parent.vue -->
<template><Child ref="childRef" />
</template><script setup>
import { ref, onMounted } from 'vue';
import Child from './Child.vue';const childRef = ref(null);onMounted(() => {console.log(childRef.value); // 子组件实例
});
</script>

3.2 使用 defineExpose 暴露组件方法

默认情况下,使用 <script setup> 的组件是封闭的,父组件无法访问子组件的任何内容。需要使用 defineExpose 显式暴露:

html

<!-- Child.vue -->
<script setup>
import { ref } from 'vue';const count = ref(0);function increment() {count.value++;
}// 暴露给父组件
defineExpose({increment,count
});
</script>

现在父组件可以访问这些暴露的内容:

javascript

// 在 Parent.vue 中
onMounted(() => {childRef.value.increment(); // 调用子组件方法console.log(childRef.value.count); // 访问子组件数据
});

3.3 defineExpose 的典型用途

  1. 暴露子组件方法供父组件调用

  2. 暴露子组件状态供父组件访问

  3. 创建可复用的组件逻辑(如表单验证、对话框控制等)

四、最佳实践

  1. 命名规范:使用有意义的 ref 名称,如 formRefmodalRef 等

  2. 避免过度使用:优先考虑 props/emit 进行组件通信

  3. null 检查:访问 ref 值前检查是否为 null

  4. 组合式函数:将 ref 逻辑封装到组合式函数中提高复用性

五、总结

  • ref 是 Vue3 响应式系统的核心 API 之一

  • 模板引用可以方便地访问 DOM 元素或组件实例

  • defineExpose 用于控制子组件向父组件暴露的内容

  • 合理使用这些特性可以创建更灵活、更易维护的组件

http://www.lryc.cn/news/624016.html

相关文章:

  • 数据结构初阶(18)快速排序·深入优化探讨
  • 【深度学习-基础知识】单机多卡和多机多卡训练
  • oom 文件怎么导到visualvm分析家
  • 生成模型实战 | InfoGAN详解与实现
  • 停车位 车辆
  • AI出题人给出的Java后端面经(十七)(日更)
  • 【URP】[法线贴图]为什么主要是蓝色的?
  • YoloV9改进策略:Block改进-DCAFE,并行双坐标注意力机制,增强长程依赖与抗噪性-即插即用
  • LangChain4j
  • Java 学习笔记(基础篇4)
  • C++零拷贝网络编程实战:从理论到生产环境的性能优化之路
  • JavaScript 性能优化实战:从评估到落地的全链路指南
  • SparkSQL性能优化实践指南
  • 第16节:自定义几何体 - 从顶点构建3D世界
  • 【FreeRTOS】刨根问底6: 应该如何防止任务栈溢出?
  • 【网络安全】Webshell的绕过——绕过动态检测引擎WAF-缓存绕过(Hash碰撞)
  • 什么是GD库?PHP中7大类64个GD库函数用法详解
  • 日语学习-日语知识点小记-进阶-JLPT-N1阶段蓝宝书,共120语法(3):21-30语法
  • 【AI论文】序曲(PRELUDE):一项旨在考察对长文本语境进行全局理解与推理能力的基准测试
  • PHP静态类self和static用法
  • 6-服务安全检测和防御技术
  • Tomcat Service 服务原理
  • Coin与Token的区别解析
  • java八股文-(spring cloud)微服务篇-参考回答
  • C语言基础:(十六)深入理解指针(6)
  • Centos 更新/修改宝塔版本
  • Rust 入门 生命周期(十八)
  • react echarts图表监听窗口变化window.addEventListener(‘resize’)与ResizeObserver()
  • 音乐创作魔法:解锁和弦与旋律的变化技巧
  • 3D打印——给开发板做外壳