Vue3-21-组件-子组件给父组件发送事件

情景描述

【子组件】中有一个按钮,点击按钮,触发一个事件,
我们希望这个事件的处理逻辑是,给【父组件】发送一条消息过去,
从而实现 【子组件】给【父组件】通信的效果。

这个问题的解决就是 “发送事件” 这个操作。
本文就针对此操作进行详细的介绍。

子组件发送事件的两种方式

【子组件】 发送事件有两种方式:
方式一 : html模板中直接使用 “$emit” 的方式发送事件;
方式二 : 使用“defineEmits()” 来声明要发送的事件。
      
【子组件】在发送事件的时候也可以携带参数。
【defineEmits() 声明式的方式 可以进行类型参数的定义】

下面是案例代码:

方式一 :$emit 直接发送事件

$emit() 可以在html模板中直接使用
$emit() 的第一个参数是 发送的事件的名称,【推荐使用驼峰命名法进行命名】
$emit() 从第二个参数开始是 发送事件所携带的参数,父组件中可以直接获取到

1、无参数

子组件

<template>

    <!-- 子组件 -->
    <div class="childdiv">
        
        子组件 - msg : {{ msg }}
        <br>
        <!-- 直接指定发送的事件的名称 -->
        <button @click="$emit('sayHello')">点我发送一个事件</button>

    </div>
    
</template>
    
<script setup lang="ts">

    import { ref } from 'vue'

    // 声明一个变量
    const msg = ref('这是子组件的msg变量')

</script>
    
<style scoped>

    .childdiv{
        width: 300px;
        border: 1px solid green;
    }

</style>

父组件

<template>

    <div class="basediv">
      
        父组件msg : {{ msg }}

        <br>
        <br>
        <!-- 子组件的使用 : 监听子组件的事件  : 
        	@后面的事件名称要与子组件中的对应起来;
        	= 后面的函数名称是自己定义的要处理的逻辑-->
        <ChildComponent @say-hello="acceptSayHello"/>
    
    </div>
    
</template>
    
<script setup lang="ts">

    import { ref } from 'vue'

    // 引入子组件
    import ChildComponent from './ChildComponent.vue'

    // 声明父组件的一个变量
    const msg = ref('这是父组件的msg变量')

    // 接收到子组件中的发送的事件
    const acceptSayHello = ()=>{
        console.log('父组件接收到子组件发送的事件 : sayHello')
    }
    
</script>
    
<style scoped>

    .basediv{
        width: 400px;
        height: 200px;
        border: 1px solid red;
    }
</style>

运行效果

在这里插入图片描述

2、有参数

子组件

<template>

    <!-- 子组件 -->
    <div class="childdiv">
        
        子组件 - msg : {{ msg }}
        <br>
        <button @click="$emit('sayHello',100,'这是参数2',true,{'aa':'对象参数'})">点我发送一个带参数的事件</button>

    </div>
    
</template>
    
<script setup lang="ts">

    import { ref } from 'vue'

    // 声明一个变量
    const msg = ref('这是子组件的msg变量')

</script>
    
<style scoped>

    .childdiv{
        width: 300px;
        border: 1px solid green;
    }

</style>

父组件

<template>

    
    <div class="basediv">
      
        父组件msg : {{ msg }}

        <br>
        <br>
        <!-- 子组件的使用 : 监听子组件的事件  : 
        	@后面的事件名称要与子组件中的对应起来;
        	= 后面的函数名称是自己定义的要处理的逻辑;
        	只写自己处理的函数名即可,无需写参数名,在逻辑处理中自动就会有的-->
        <ChildComponent @say-hello="acceptSayHello"/>
    
    </div>
    
  
</template>
    
<script setup lang="ts">

    import { ref } from 'vue'

    // 引入子组件
    import ChildComponent from './ChildComponent.vue'

    // 声明父组件的一个变量
    const msg = ref('这是父组件的msg变量')

    // 接收到子组件中的发送的事件 : 参数直接在函数声明中接收即可
    const acceptSayHello = (p1:number,p2:string,p3:boolean,p4:object)=>{
        console.log('父组件接收到子组件发送的事件-带参数的 : sayHello')
        console.log('父组件接收到子组件发送的事件-p1 : ',p1)
        console.log('父组件接收到子组件发送的事件-p2 : ',p2)
        console.log('父组件接收到子组件发送的事件-p3 : ',p3)
        console.log('父组件接收到子组件发送的事件-p4 : ',p4)
    }

</script>
    
<style scoped>

    .basediv{
        width: 400px;
        height: 200px;
        border: 1px solid red;
    }
</style>

运行效果

在这里插入图片描述

方式二 :defineEmits() 声明式发送事件

defineEmits() 的声明语法 : const emitEvents = defineEmits(['事件名称1','事件名称2',...])
发送事件的方式 : emitEvents('事件名称',参数1,参数2,...)
扩展 : 通过 defineEmits() 声明事件的方式,可以使用ts 中的方法签名,使事件信息更完善。

1、无参数

子组件

<template>

    <!-- 子组件 -->
    <div class="childdiv">
        
        子组件 - msg : {{ msg }}
        <br>
        <button @click="sendEmit">点我发送一个defineEmits声明的事件</button>

    </div>
    
</template>
    
<script setup lang="ts">

    import { ref } from 'vue'

    // 声明一个变量
    const msg = ref('这是子组件的msg变量')

    // 声明事件
    const emitsEventList = defineEmits(['sayHello'])

    // 点击按钮,发送事件
    const sendEmit = ()=>{
        console.log('子组件点击了按钮,发送事件-无参')
        emitsEventList('sayHello')
    }

</script>
    
<style scoped>

    .childdiv{
        width: 300px;
        border: 1px solid green;
    }

</style>

父组件

<template>

    <div class="basediv">
      
        父组件msg : {{ msg }}

        <br>
        <br>
        <!-- 子组件的使用 : 监听子组件的事件  : 
        	@后面的事件名称要与子组件中的对应起来;
        	= 后面的函数名称是自己定义的要处理的逻辑-->
        <ChildComponent @say-hello="acceptSayHello"/>
    
    </div>
    
  
</template>
    
<script setup lang="ts">

    import { ref } from 'vue'

    // 引入子组件
    import ChildComponent from './ChildComponent.vue'

    // 声明父组件的一个变量
    const msg = ref('这是父组件的msg变量')

    // 接收到子组件中的发送的事件
    const acceptSayHello = ()=>{
        console.log('父组件接收到子组件发送的事件-无参数的 : sayHello')
    }

</script>
    
<style scoped>

    .basediv{
        width: 400px;
        height: 200px;
        border: 1px solid red;
    }
</style>

运行效果

在这里插入图片描述

2、有参数

子组件

<template>

    <!-- 子组件 -->
    <div class="childdiv">
        
        子组件 - msg : {{ msg }}
        <br>
        <button @click="sendEmit">点我发送一个defineEmits声明的带参数的事件</button>

    </div>
    
</template>
    
<script setup lang="ts">

    import { ref } from 'vue'

    // 声明一个变量
    const msg = ref('这是子组件的msg变量')

    // 声明事件
    const emitsEventList = defineEmits(['sayHello'])

    // 点击按钮,发送事件 : 带参数的事件
    const sendEmit = ()=>{
        console.log('子组件点击了按钮,发送事件-带参数')
        emitsEventList('sayHello',100,'第二个参数',false,{"aa":"对象参数的第一个属性aa"})
    }

</script>
    
<style scoped>

    .childdiv{
        width: 300px;
        border: 1px solid green;
    }

</style>

父组件

<template>

    <div class="basediv">
      
        父组件msg : {{ msg }}

        <br>
        <br>
        <!-- 子组件的使用 : 监听子组件的事件  : 
        	@后面的事件名称要与子组件中的对应起来;
        	= 后面的函数名称是自己定义的要处理的逻辑-->
        <ChildComponent @say-hello="acceptSayHello"/>
    
    </div>
    
</template>
    
<script setup lang="ts">

    import { ref } from 'vue'

    // 引入子组件
    import ChildComponent from './ChildComponent.vue'

    // 声明父组件的一个变量
    const msg = ref('这是父组件的msg变量')

    // 接收到子组件中的发送的事件
    const acceptSayHello = (p1:number,p2:string,p3:boolean,p4:object)=>{
        console.log('父组件接收到子组件发送的事件-带参数的 : sayHello')
        console.log('父组件接收到子组件使用defineEmits发送的事件-p1 : ',p1)
        console.log('父组件接收到子组件使用defineEmits发送的事件-p2 : ',p2)
        console.log('父组件接收到子组件使用defineEmits发送的事件-p3 : ',p3)
        console.log('父组件接收到子组件使用defineEmits发送的事件-p4 : ',p4)

    }

</script>
    
<style scoped>

    .basediv{
        width: 400px;
        height: 200px;
        border: 1px solid red;
    }
</style>

运行效果

在这里插入图片描述

补充 : 为事件标注类型的写法

【子组件】在使用defineEmits() 声明事件的时候,写成一个函数签名的方式,
指定 时间的名称和参数列表,
这样在编码的时候会有类型约束,看上去更加的规范一些。

子组件

<template>

    <!-- 子组件 -->
    <div class="childdiv">
        
        子组件 - msg : {{ msg }}
        <br>
        <button @click="sendEmit">点我发送一个defineEmits声明的带参数的有类型标注的事件</button>

    </div>
    
</template>
    
<script setup lang="ts">

    import { ref } from 'vue'

    // 声明一个变量
    const msg = ref('这是子组件的msg变量')

    // 声明事件 : 使用类型标注的方式来声明 : 直接声明一个函数的意思就是
    const emitsEventList = defineEmits<{
        (e:'sayHello',id:number,namep:string):void
    }>()

    // 点击按钮,发送事件 : 带参数的事件
    const sendEmit = ()=>{
        console.log('子组件点击了按钮,发送事件-带参数')
        emitsEventList('sayHello',200,'第二个参数')
    }
     
</script>
    
<style scoped>

    .childdiv{
        width: 300px;
        border: 1px solid green;
    }

</style>

父组件

<template>

    <div class="basediv">
      
        父组件msg : {{ msg }}

        <br>
        <br>
        <!-- 子组件的使用 : 监听子组件的事件  : 
        	@后面的事件名称要与子组件中的对应起来;
        	= 后面的函数名称是自己定义的要处理的逻辑-->
        <ChildComponent @say-hello="acceptSayHello"/>
    
    </div>
    
</template>
    
<script setup lang="ts">

    import { ref } from 'vue'

    // 引入子组件
    import ChildComponent from './ChildComponent.vue'

    // 声明父组件的一个变量
    const msg = ref('这是父组件的msg变量')

    // 接收到子组件中的发送的事件
    const acceptSayHello = (p1:number,p2:string)=>{
        console.log('父组件接收到子组件发送的事件-带参数的 : sayHello')
        console.log('父组件接收到子组件使用defineEmits发送的事件-p1 : ',p1)
        console.log('父组件接收到子组件使用defineEmits发送的事件-p2 : ',p2)

    }

</script>
    
<style scoped>

    .basediv{
        width: 400px;
        height: 200px;
        border: 1px solid red;
    }
</style>

运行效果

在这里插入图片描述

在这里插入图片描述

父组件接收事件的方式

【父组件】接收事件的方式比较简单,就像监听普通元素的事件一样,可以直接使用语法糖 @ 符号来监听事件,
【注意点1】 :
	【子组件】中声明事件的时候,事件的名称 使用的 “驼峰命名法”,例如 "sayHello";
	【父组件】中监听事件的时候,需要使用 “中划线”的命名方式,例如 "@say-hello="xxxxxx""。

【注意点2】:
【父组件】中监听【子组件】的事件的时候,
如果有参数,【父组件】中的方法可以直接写参数就好了,接收的过程会自动匹配,
无需关心 参数名的问题,接收到就可以使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/250394.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

玩转大数据18:大规模数据处理与分布式任务调度

引言 在数字化时代&#xff0c;数据成为了一种宝贵的资源&#xff0c;对于企业和组织来说&#xff0c;如何有效地处理和分析这些数据成为了关键的竞争力。大规模数据处理与分布式任务调度作为大数据处理的核心技术&#xff0c;为解决这一问题提供了有效的解决方案。 随着数据…

36个校招网络原理面试题

1.如何理解 URI&#xff1f; URI, 全称为(Uniform Resource Identifier), 也就是统一资源标识符&#xff0c;它的作用很简单&#xff0c;就是区分互联网上不同的资源。但是&#xff0c;它并不是我们常说的网址, 网址指的是URL, 实际上URI包含了URN和URL两个部分&#xff0c;由…

gitbash下载安装

参考教程 零、下载 官网地址 2.43.0win64 链接&#xff1a;https://pan.baidu.com/s/16urs_nmky7j20-qNzUTTkg 提取码&#xff1a;7jaq 一、安装 图标组件&#xff08;Additional icons&#xff09;&#xff1a;选择是否创建桌面快捷方式&#xff1b;桌面浏览&#xff08;Win…

【后端卷前端3】

侦听器 监听的数据是 data()中的动态数据~响应式数据 <template><div><p>{{showHello}}</p><button click"updateHello">修改数据</button></div> </template><script>export default {name: "goodsTe…

GraphicsProfiler 使用教程

GraphicsProfiler 使用教程 1.工具简介&#xff1a;2.Navigation介绍2.1.打开安装好的Graphics Profiler。2.2.将手机连接到计算机&#xff0c;软件会在手机中安装一个GraphicsProfiler应用(该应用是无界面的&#xff09;。2.3.Show files list2.4.Record new trace2.4.1.Appli…

【Redis】Redis.conf详解

Redis.conf详解 启动的时候&#xff0c;就通过配置文件来启动&#xff01; 工作中&#xff0c;一些小小的配置&#xff0c;可以让你脱颖而出&#xff01; 单位 配置文件 unit单位 对大小写不敏感&#xff01;include包含其他配置文件 就是好比我们学习Spring、Improt&#x…

计算机网络考研辨析(后续整理入笔记)

考完研补充题目图片进来。 方老师课程还有一些细节不够到位&#xff0c;不影响学习&#xff0c;但是初期如果想得多了&#xff0c;会有一些迷惑&#xff0c;后续要把这些补进去文章里&#xff0c;让文章更加好。 这里做出细化&#xff0c;尤其是针对数字&#xff0c;计算&…

YOLOv7原创改进:一种新颖的跨通道交互的高效率通道注意力EMCA,ECA注意力改进版

💡💡💡本文原创自研创新改进:基于ECA注意力,提出了一种新颖的EMCA注意力(跨通道交互的高效率通道注意力),保持高效轻量级的同时,提升多尺度提取能力 强烈推荐,适合直接使用,paper创新级别 💡💡💡 在多个数据集验证涨点,尤其对存在多个尺度的数据集涨点明…

视频监控管理平台/智能监测/检测系统EasyCVR中HLS流无法播放的解决方案

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

使用Go实现一个百行聊天服务器

前段时间, redis作者不是整了个c语言版本的聊天服务器嘛, 地址, 代码量拢共不过百行. 于是, 心血来潮下, 我也整了个Go语言版本. 简单来说就是实现了一个聊天室的功能. 将所有注释空行都去掉, 刚好100行实现. 废话不多说, 先上代码: package mainimport ("fmt"&quo…

基于SSM的实践项目管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

冗余备份组网——HSRP和GLBP协议

目录 HSRP&#xff08;思科私有协议&#xff09; HSRP基本概念 HSRP工作过程 HSRP的状态 HSRP的可靠性 HSRP相关配置 GLBP协议 HSRP&#xff08;思科私有协议&#xff09; HSRP基本概念 HSRP&#xff08;Host Standby Router Protocol&#xff09;为主机备份路由协议 …

Chapter 7 - 3. Congestion Management in Ethernet Storage Networks以太网存储网络的拥塞管理

Pause Threshold for Long Distance Links长途链路的暂停阈值 This section uses the following basic concepts: 本节使用以下基本概念: Bit Time (BT): It is the time taken to transmit one bit. It is the reciprocal of the bit rate. For example, BT of a 10 GbE po…

Linux系统编程(二):标准 I/O 库(下)

参考引用 UNIX 环境高级编程 (第3版)嵌入式Linux C应用编程-正点原子 1. 标准 I/O 库简介 标准 I/O 库是指&#xff1a;标准 C 库中用于文件 I/O 操作&#xff08;如&#xff1a;读、写文件等&#xff09;相关的一系列库函数的集合 标准 I/O 库函数相关的函数定义都在头文件 &…

强化学习--免模型预测与控制

免模型预测与控制 强化学习 免模型预测与控制免模型预测蒙特卡洛估计时序差分估计时序产分与蒙特卡洛的比较免模型控制Q-learning 免模型预测 蒙特卡洛估计 蒙特卡洛估计方法在强化学习中是免模型预测价值函数的方式之一&#xff0c;本质是一种统计模拟方法&#xff0c;它的发…

FIFO的Verilog设计(三)——最小深度计算

文章目录 前言一、FIFO的最小深度写速度快于读速度写速度等于或慢于读速度 二、 举例说明1. FIFO写时钟为100MHz&#xff0c;读时钟为80Mhz情况一&#xff1a;一共需要传输2000个数据&#xff0c;求FIFO的最小深度情况二&#xff1a;100个时钟写入80个数据&#xff0c;1个时钟读…

【VMware安装及虚拟机配置】

1. 下载VMware 进入 VMware Workstation 17 Pro下载链接 下拉到如下位置&#xff0c;点击DOWNLOAD 2. 安装VMware 参考&#xff1a;虚拟机VMware下载与安装教程 本次安装是vmware 17&#xff0c;安装步骤差不多&#xff0c;只参考第二部分即可。 3. 激活VMware 密钥&…

12345、ABCDE项目符号列表文字视频怎么制作?重点内容介绍PR标题模板项目工程文件

Premiere模板&#xff0c;包含10个要点标题12345、ABCDE项目符号列表文字模板PR项目工程文件。可以根据自己的需要定制颜色。在视频的开头、中间和结尾使用。包括视频教程。 适用软件&#xff1a;Premiere Pro 2019 | 分辨率&#xff1a;19201080 (HD) | 文件大小&#xff1a;9…

十九)Stable Diffusion使用教程:ai室内设计案例

今天我们聊聊如何通过SD进行室内设计装修。 方式一:controlnet的seg模型 基础起手式: 选择常用算法,抽卡: 抽到喜欢的图片之后,拖到controlnet里: 选择seg的ade20k预处理器,点击爆炸按钮,得到seg语义分割图,下载下来: 根据语义分割表里的颜色值,到PS里进行修改: 语…

【linux】图形界面Debian的root用户登陆

图形界面Debian默认不允许以root用户登录。这是出于安全考虑&#xff0c;以防止用户使用root权限执行可能损害系统的操作。 如果需要使用root用户&#xff0c;可以通过以下步骤进行登录&#xff1a; 打开终端&#xff0c;使用su命令切换到root用户。修改/etc/gdm3/daemon.con…