深入解析 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查看…...
国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
全志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…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
