深入解析 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查看…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
