深入解析 Vue 3 中的 defineExpose
深入解析 Vue 3 中的 defineExpose
在 Vue 3 的组合式 API(Composition API)中,defineExpose
是一个重要的辅助函数,专门用于在 <script setup>
模式下暴露组件内部的属性和方法给父组件使用。本文将详细解析 defineExpose
的功能、使用场景及注意事项,并结合实际代码示例帮助你更好地理解和应用。
1. 什么是 defineExpose
?
defineExpose
是 Vue 3 提供的一个仅能在 <script setup>
中使用的函数,用来显式暴露组件内部的属性或方法,使得父组件可以通过 ref
访问子组件的暴露内容。
作用
- 在 Vue 3 中,
<script setup>
默认是封闭的。子组件的内容不会自动暴露给父组件。 - 使用
defineExpose
可以选择性地暴露内部内容,从而避免不必要的属性泄漏,同时提供更好的封装性。
2. 基本用法
语法
defineExpose(exposedObject)
- 参数:
exposedObject
,一个对象,定义要暴露的属性或方法。 - 返回值:无。
示例:暴露方法和数据
<script setup>
import { ref } from 'vue';// 子组件内部的状态和方法
const count = ref(0);function increment() {count.value++;
}// 通过 defineExpose 暴露给父组件
defineExpose({count,increment
});
</script><template><div><p>计数器子组件:{{ count }}</p></div>
</template>
在父组件中:
<script setup>
import { ref } from 'vue';
import Counter from './Counter.vue';// 通过 ref 获取子组件实例
const counterRef = ref(null);function callChildMethod() {counterRef.value.increment(); // 调用子组件的方法console.log('子组件计数值:', counterRef.value.count); // 访问子组件的暴露属性
}
</script><template><Counter ref="counterRef" /><button @click="callChildMethod">调用子组件方法</button>
</template>
运行结果
- 点击按钮,父组件调用子组件的
increment
方法,子组件的count
值增加。 - 父组件通过子组件的
ref
访问到了count
和increment
。
3. 为什么需要 defineExpose
?
默认行为:封闭的 <script setup>
在 Vue 3 的 <script setup>
中,组件的状态和方法默认是私有的。这意味着,父组件即使通过 ref
引用子组件实例,也无法访问其中的任何内容。
例如:
<script setup>
const msg = 'Hello Vue';
</script>
在父组件中,即使通过 ref
获取子组件,也无法访问 msg
。
显式暴露:提高安全性
通过 defineExpose
,开发者可以显式选择要暴露的内容,从而避免父组件访问到不必要的内部状态或方法,提供更好的组件封装性。
4. defineExpose
的典型使用场景
4.1 暴露组件方法
当父组件需要调用子组件的方法时,可以使用 defineExpose
。
<script setup>
function greet() {console.log('子组件方法被调用!');
}
defineExpose({ greet });
</script>
在父组件中:
<template><ChildComponent ref="child" /><button @click="child.greet()">调用子组件方法</button>
</template><script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';const child = ref(null);
</script>
4.2 配合动态模板或状态管理
当子组件需要暴露动态状态供父组件使用时:
<script setup>
import { ref } from 'vue';const isLoading = ref(false);function startLoading() {isLoading.value = true;
}function stopLoading() {isLoading.value = false;
}defineExpose({ isLoading, startLoading, stopLoading });
</script>
父组件:
<script setup>
import ChildComponent from './ChildComponent.vue';
import { ref } from 'vue';const childRef = ref(null);function toggleLoading() {childRef.value.startLoading();setTimeout(() => {childRef.value.stopLoading();}, 2000);
}
</script><template><ChildComponent ref="childRef" /><button @click="toggleLoading">加载 2 秒</button>
</template>
4.3 复杂场景:动态父子组件交互
有时父组件需要根据子组件的状态动态渲染内容,例如表单校验、步骤管理等。
示例:子组件暴露校验方法
<script setup>
import { ref } from 'vue';const formData = ref({ name: '', age: null });function validate() {const isValid = formData.value.name !== '' && formData.value.age > 0;return isValid;
}defineExpose({ formData, validate });
</script><template><div><input v-model="formData.name" placeholder="输入姓名" /><input v-model="formData.age" type="number" placeholder="输入年龄" /></div>
</template>
父组件调用校验:
<script setup>
import { ref } from 'vue';
import FormComponent from './FormComponent.vue';const formRef = ref(null);function submitForm() {if (formRef.value.validate()) {console.log('表单校验通过!');} else {console.log('表单校验失败!');}
}
</script><template><FormComponent ref="formRef" /><button @click="submitForm">提交</button>
</template>
5. 注意事项
-
只能在
<script setup>
中使用:
defineExpose
是专为<script setup>
设计的,不能用于普通的<script>
或setup()
函数中。 -
明确暴露的内容:
不建议直接暴露整个组件内部状态,应该只暴露必要的部分,保持组件封装性。 -
ref
必须正确绑定:
父组件只有在为子组件设置了ref
属性后,才能通过ref
访问子组件的暴露内容。 -
避免滥用:
如果父组件频繁依赖子组件的内部状态,可能说明父组件和子组件的职责划分不清。
6. 总结
defineExpose
是 Vue 3 中一个强大的辅助函数,用于在封闭的 <script setup>
模式下显式暴露组件的部分内容。它增强了组件间的交互能力,同时保持了组件的封装性。通过合理使用 defineExpose
,可以提高代码的灵活性和可维护性。
希望这篇文章能够帮助你全面掌握 defineExpose
的使用!如果你对 Vue 3 的其他特性感兴趣,欢迎留言讨论! 😊
相关文章:
深入解析 Vue 3 中的 defineExpose
深入解析 Vue 3 中的 defineExpose 在 Vue 3 的组合式 API(Composition API)中,defineExpose 是一个重要的辅助函数,专门用于在 <script setup> 模式下暴露组件内部的属性和方法给父组件使用。本文将详细解析 defineExpose…...

Docker3:docker基础1
欢迎来到“雪碧聊技术”CSDN博客! 在这里,您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者,还是具有一定经验的开发者,相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导,我将…...
【UGUI】背包的交互01(道具信息跟随鼠标+道具信息面板显示)
详细程序逻辑过程 初始化物品栏: 在 Awake 方法中,通过标签找到提示框和信息面板。 循环生成10个背包格子,并为每个格子设置图标和名称。 为每个格子添加 UInterMaager232 脚本,以便处理交互事件。 关闭提示框和信息面板&#…...
ubuntu20.04中编译安装gcc 9.2.0
ubuntu20.04中编译安装gcc 9.2.0,步骤如下: #install compile dependence libraries 1:$ sudo apt install libgmp-dev libisl-dev libmpc-dev libmpfr-dev # install gcc 9.2.0 # download source code 2:$ wget http://ftp.gnu.org/gn…...
ss 命令的基本用法
ss 命令的基本用法 ss [选项]-tanl 选项解释 -t:显示 TCP 连接。-a:显示所有连接(包括监听端口)。-n:显示数字形式的地址和端口号,而不是解析为主机名和服务名。-l:仅显示监听的端口。 使用示…...

Leetcode198. 打家劫舍(HOT100)
代码: class Solution { public:int rob(vector<int>& nums) {int n nums.size();vector<int> f(n 1), g(n 1);for (int i 1; i < n; i) {f[i] g[i - 1] nums[i - 1];g[i] max(f[i - 1], g[i - 1]);}return max(f[n], g[n]);} }; 这种求…...

kafka基础
文章目录 一、Kafka入门1.1、JMS1.2、生产者-消费者模式1.3、ZooKeeper 二、kafka基础架构2.1、producer2.2、kafka cluster2.2.1、broker2.2.2、Controller2.2.3、Topic2.2.4、Partition2.2.5、Replication2.2.6、Leader & Follower 2.3、consumer 一、Kafka入门 Kafka是一…...

STM32CUBEIDE FreeRTOS操作教程(九):eventgroup事件标志组
STM32CUBEIDE FreeRTOS操作教程(九):eventgroup事件标志组 STM32CUBE开发环境集成了STM32 HAL库进行FreeRTOS配置和开发的组件,不需要用户自己进行FreeRTOS的移植。这里介绍最简化的用户操作类应用教程。以STM32F401RCT6开发板为…...
Python设计模式详解之2 —— 工厂模式
工厂模式(Factory Pattern)是一种创建型设计模式,旨在定义一个用于创建对象的接口,但由子类决定实例化哪个类。工厂模式可以帮助我们将对象的创建与其使用分离,增强代码的可扩展性和维护性。 工厂模式的分类 简单工厂…...

【Zookeeper】二、主从应用(master-worker架构)
以一张具有代表性的架构风格展开本篇论述 一般在这种架构中,主节点所负责的工作主要有 跟踪从节点状态分配任务到从节点,并跟踪任务的有效性(任务是否正常执行完成) 此时,我们需要关注三个问题 主节点崩溃 如果主节…...

Diffusion【2】:VAE
系列文章目录 文章目录 系列文章目录前言1. Abstract2. Introduction2.1. Motivation2.2. Contribution 3. Methods3.1. Problem Scenario3.2. The variational bound3.3. The SGVB estimator and AEVB algorithm3.3.1. Stochastic Gradient Variational Bayes Estimator3.3.2.…...
高级java每日一道面试题-2024年11月19日-基本篇-获取一个类Class对象的方式有哪些?
如果有遗漏,评论区告诉我进行补充 面试官: 获取一个类Class对象的方式有哪些? 我回答: 在 Java 中,获取一个类的 Class 对象有多种方式。这些方式各有优缺点,适用于不同的场景。以下是常见的几种方法及其详细解释: 1. 使用 new 关键字实…...
xilinx xapp1171学习笔记
在xapp1171示例中,假设Host PC将PCIE:BAR0赋值为:0x00000000_def00000 PCIEBAR2AXIBAR_00x81000000,即Host PC读写0x00000000_def00000就是在读写AXI地址0x81000000(BRAM在AXI总线上的基地址) 在AXI总线上࿰…...

一次需升级系统的wxpython安装(macOS M1)
WARNING: The scripts libdoc, rebot and robot are installed in /Users/用户名/Library/Python/3.8/bin which is not on PATH. 背景:想在macos安装Robot Framework ,显示pip3不是最新,更新pip3后显示不在PATH上 参看博主文章末尾 MAC系统…...

el-table 数据去重后合并表尾合计行,金额千分位分割并保留两位小数,表尾合计行表格合并
问题背景 最近在做后台管理项目el-table 时候需要进行表尾合计,修改合计后文字的样式,合并单元格。 想实现的效果 合并表尾单元格前三列为1格;对某些指定的单元格进行表尾合计;合计后的文本样式加粗;涉及到金额需要千…...
Springboot整合mybatis-plus使用pageHelper进行分页
PageHelper 使用步骤全解析 在进行 Web 应用开发时,经常会涉及到数据库数据的分页展示。PageHelper 是一个非常实用的 MyBatis 分页插件,它能够方便地实现数据库查询结果的分页功能,极大地提高了开发效率。以下将简单介绍 PageHelper 的使用…...

【Xbim+C#】创建拉伸的墙
基础 基础回顾 效果图 简单的工具类 using System.Collections.Generic; using System.Linq; using Xbim.Common.Step21; using Xbim.Ifc; using Xbim.Ifc4.GeometricConstraintResource; using Xbim.Ifc4.GeometricModelResource; using Xbim.Ifc4.GeometryResource; using…...

【阅读记录-章节3】Build a Large Language Model (From Scratch)
目录 3 Coding attention mechanisms3.1 The problem with modeling long sequences背景:注意力机制的动机 3.2 Capturing data dependencies with attention mechanismsRNN的局限性与改进Transformer架构的革命 3.3 Attending to different parts of the input wit…...

three.js 对 模型使用 视频进行贴图修改材质
three.js 对 模型使用 视频进行贴图修改材质 https://threehub.cn/#/codeMirror?navigationThreeJS&classifyapplication&idvideoModel import * as THREE from three import { OrbitControls } from three/examples/jsm/controls/OrbitControls.js import { GLTFLoad…...

MySQL - 数据库基础 | 数据库操作 | 表操作
文章目录 1、数据库基础1.1为什么要有数据库1.2主流的数据库1.3连接MySQL1.4服务器、数据库、表的关系1.5 MySQL框架1.6 SQL分类1.7储存引擎 2.数据库操作2.1创建数据库2.2字符集和校验规则2.3删除数据库2.4修改数据库2.5备份与恢复2.6查看连接情况 3.表的操作3.1创建表3.2查看…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3
一,概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本:2014.07; Kernel版本:Linux-3.10; 二,Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01),并让boo…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

如何应对敏捷转型中的团队阻力
应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中,明确沟通敏捷转型目的尤为关键,团队成员只有清晰理解转型背后的原因和利益,才能降低对变化的…...