Vue3中的常见组件通信之props和自定义事件

Vue3中的常见组件通信

概述

​ 在vue3中常见的组件通信有props、mitt、v-model、 r e f s 、 refs、 refsparent、provide、inject、pinia、slot等。不同的组件关系用不同的传递方式。常见的撘配形式如下表所示。

组件关系传递方式
父传子1. props
2. v-model
3. $refs
4. 默认插槽、具名插槽
子传父1. props
2. 自定义事件
3. v-model
4. $parent
5. 作用域插槽
祖传孙、孙传祖1. $attrs
2. provide、inject
兄弟间、任意组件间1. mitt
2. pinia

​ 本文讲述props和自定义事件,其他的通信方式后面再更新。

1.props

1.1 准备父子组件

首先准备一个简单的父子组件的样式,如下是父组件代码:

<template><div class="father"><h2>这是父组件</h2><Child/></div>
</template><script setup lang="ts" name="Father">//引入子组件import Child from './Child.vue';</script><style scoped>.father{margin: 5px;background-color:rgb(205, 165, 32);padding: 20px;color: white;}
</style>

以下是子组件代码:

<template><div class="child"><h2>这是子组件</h2></div>
</template><script setup lang="ts" name="Child"></script><style scoped>.child{margin: 5px;background-color: rgba(93, 135, 20, 0.224);border: 1px solid;border-color: white;box-shadow: 0 0 5px;padding: 10px;color: #000;}	
</style>

运行结果如下所示:

image-20240601203254108

1.2 父传子通信的实现

用props实现父传子通信,可以用标签中的属性值直接传递数据,父组件代码中只需要在子组件标签上添加属性值即可,如下代码,传递两个数据:

<Child :f2CMsg="f2CMsg" :f2CObj="f2CObj"/>

定义传递的数据内容,两个数据分别是ref定义的基本类型的响应式数据和reactive定义的对象类型的响应式数据。

//引入ref和reactive
import {ref,reactive} from 'vue'//数据,ref定义的基本类型的响应式数据
let f2CMsg =ref('你好,子组件。')//数据,reactive定义的对象类型的响应式数据
let f2CObj = reactive({
id:"asdfg01",
name:"张三",
age:18,
detail:"这是父组件中的对象信息"
})

在子组件中需要声明接收数据props,注意接收的数据格式是数组,哪怕是只传递一个数据也要写成数组的形式。

//声明接收数据props
defineProps(['f2CMsg','f2CObj'])

子组件中在页面展示接收的数据,如下代码:

<h4>父组件传递的信息:{{ f2CMsg }}</h4>
<h4>父组件传递的对象:</h4>
<ul><li>姓名:{{f2CObj.name}}</li><li>年龄:{{f2CObj.age}}</li><li>详情:{{f2CObj.detail}}</li>
</ul>

然后运行结果如下:

image-20240601211035944

1.3 子传父通信的实现

用props实现子传父的通信需要父组件先向子组件传递一个函数,然后传递的数据以参数的形式传递给函数,父组件中先定义子传父的数据变量和函数或者方法如下:

//定义子传父的数据变量
let c2FMsg = ref('')
//定义方法传递给子组件
function getMsg(value:string){c2FMsg.value = value
}

在标签中把方法传给子组件:

<Child :f2CMsg="f2CMsg" :f2CObj="f2CObj" :sendMsg="getMsg"/>

在子组件中接收数据,并定义数据内容:

defineProps(['f2CMsg','f2CObj','sendMsg'])
let c2FMsg = ref('你好,父组件。')

在子组件中设置一个按钮,给按钮绑定点击事件,点击事件触发sendMsg方法,并传递参数:

<button @click="sendMsg(c2FMsg)">点我向父组件传递信息</button>

现在数据应该已经传递给了父组件,在父组件可以用如下代码展示:

<h4 v-show="c2FMsg">子组件传递的信息:{{ c2FMsg }}</h4>

运行结果如下:

image-20240601213552916

点击按钮后运行结果如下:

image-20240601213621311

至此我们已经用props实现了子传父的通信功能。当然子传父也可以传递对象。此处不再展示。如下是完整代码:

父组件中的代码:

<template><div class="father"><h2>这是父组件</h2><h4 v-show="c2FMsg">子组件传递的信息:{{ c2FMsg }}</h4>	<Child :f2CMsg="f2CMsg" :f2CObj="f2CObj" :sendMsg="getMsg"/>	</div>
</template><script setup lang="ts" name="Father">//引入子组件import Child from './Child.vue';//引入ref和reactiveimport {ref,reactive} from 'vue'//数据,ref定义的基本类型的响应式数据let f2CMsg =ref('你好,子组件。')//数据,reactive定义的对象类型的响应式数据let f2CObj = reactive({id:"asdfg01",name:"张三",age:18,detail:"这是父组件中的对象信息"})//定义子传父的数据变量let c2FMsg = ref('')//定义方法传递给子组件function getMsg(value:string){c2FMsg.value = value		}
</script><style scoped>.father{margin: 5px;background-color:rgb(205, 165, 32);padding: 20px;color: white;}
</style>

子组件的代码:

<template><div class="child"><h2>这是子组件</h2><h4>父组件传递的信息:{{ f2CMsg }}</h4><h4>父组件传递的对象:</h4><ul><li>姓名:{{f2CObj.name}}</li><li>年龄:{{f2CObj.age}}</li><li>详情:{{f2CObj.detail}}</li></ul><button @click="sendMsg(c2FMsg )">点我向父组件传递信息</button></div>
</template><script setup lang="ts" name="Child">
import { ref,reactive } from 'vue';//声明接收数据props
defineProps(['f2CMsg','f2CObj','sendMsg'])let c2FMsg = ref('你好,父组件。')</script><style scoped>.child{margin: 5px;background-color: rgba(93, 135, 20, 0.224);border: 1px solid;border-color: white;box-shadow: 0 0 5px;padding: 10px;color: #000;}	
</style>

1.4 小结

用props实现父子通信的步骤是这样的:

父传子:父组件中定义传递的数据–>标签中用属性值直接传递数据–>子组件中声明接收数据–>用插值语法展示数据。

子传父: 父组件先定义接收数据的变量–>父组件中定义函数–>将函数传递给子组件–>子组件中声明接收数据,接收的数据为函数–>子组件中定义传递的数据–>子组件中调用接收的函数,将定义的要传递的数据作为参数进行传递–>父组件中收到数据,可以在页面中展示。

最后总结如下:

父传子:标签中的属性值是非函数

子传父:标签中的属性值是函数

2. 自定义事件

自定义事件通常用于子传父,需要注意在原生事件中事件名是特定的,比如click,keyup等,在自定义事件中事件名是任意的;在原生事件中事件对象 e v e n t 是包含事件相关信息的对象( ‘ p a g e X ‘ 、 ‘ p a g e Y ‘ 、 ‘ t a r g e t ‘ 、 ‘ k e y C o d e ‘ ),在定义事件中事件对象 event是包含事件相关信息的对象(`pageX`、`pageY`、`target`、`keyCode`),在定义事件中事件对象 event是包含事件相关信息的对象(pageXpageYtargetkeyCode),在定义事件中事件对象event是调用emit所提供的数据,可以是任意类型。

2.1 准备父子组件

父子组件代码与样式与本文中1.1中的完全相同,此处不再赘述。

2.2 自定义事件实现子传父通信

首先在子组件中定义要传递的数据,此次依然已字符串为例,如下代码:

let c2FMsg = ref('你好,父组件。')

然后在父组件中定义接收的数据变量,并声明函数,用来保存接收的数据。

let c2FMsg = ref('')//声明函数saveMsg,用来保存接收的数据
function saveMsg(value:string){c2FMsg.value = value
}

之后给子组件绑定自定义事件,事件名为send-message,同时将函数saveMsg传进去,注意自定义事件名的命名规范官方建议采用肉串形式的命名方式。

<!-- 给子组件绑定自定义事件 -->
<Child @send-message="saveMsg"/>

在子组件中需要声明事件

//声明事件
let emit = defineEmits(['send-message'])

触发事件的代码如下:

emit('send-message')

只要在子组件中写出上面触发事件的代码,就可以实现子传父的通信,这次以子组件挂载3秒后自动触发事件为例,如下代码:

//组件挂载3秒后触发事件
onMounted(()=>{setTimeout(()=>{//触发事件send-message,并传c2FMsgemit('send-message',c2FMsg)},3000)
})

此时已经实现了子传父的通信,最后在父组件中展示出来,如下代码:

<h3 v-show="c2FMsg">子组件传递的信息:{{ c2FMsg }}</h3>

最后运行页面效果如下,在刚启动页面是如下效果:

image-20240602105624203

3秒钟之后看下的效果如下图所示:

image-20240602105712057

以下是完整代码:

父组件代码:

<template><div class="father"><h2>这是父组件</h2><h3 v-show="c2FMsg">子组件传递的信息:{{ c2FMsg }}</h3><!-- 给子组件绑定自定义事件 --><Child @send-message="saveMsg"/></div></template><script setup lang="ts" name="Father">//引入子组件import Child from './Child.vue';import { ref } from 'vue';let c2FMsg = ref('')//声明函数,用来保存接收的数据function saveMsg(value:string){c2FMsg.value = value}</script><style scoped>.father{margin: 5px;background-color:rgb(205, 165, 32);padding: 20px;color: white;}</style>

以下是子组件代码:

<template><div class="child"><h2>这是子组件</h2></div></template><script setup lang="ts" name="Child">import {ref,onMounted} from 'vue'let c2FMsg = ref('你好,父组件。')//声明事件let emit = defineEmits(['send-message'])//组件挂载3秒后触发事件onMounted(()=>{setTimeout(()=>{//触发事件send-message,并传c2FMsgemit('send-message',c2FMsg)},3000)})</script><style scoped>.child{margin: 5px;background-color: rgba(93, 135, 20, 0.224);border: 1px solid;border-color: white;box-shadow: 0 0 5px;padding: 10px;color: #000;}	</style>

2.3 小结

以上便是自定义事件的基本用法,在实际开发中是比较常用的用来实现子传父的通信方式。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python课设-学生信息管理系统

一、效果展示图 二、前端代码 1、HTML代码 <1>index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">…

安卓模拟鼠标,绘图板操作电脑PC端,卡卡罗特也说好,儿童节快乐

家人们&#xff0c;上链接了&#xff1a;https://download.csdn.net/download/jasonhongcn/89387887

B站如何屏蔽短视频:成都鼎茂宏升文化传媒公司

B站如何屏蔽短视频&#xff1a;优化你的观看体验 在当今数字化时代&#xff0c;B站&#xff08;哔哩哔哩&#xff09;作为国内领先的弹幕视频网站&#xff0c;以其丰富的视频资源和独特的弹幕文化吸引了大量用户。然而&#xff0c;随着短视频的兴起&#xff0c;B站也引入了短视…

intel深度相机D455的使用

一、D455介绍 Intel RealSense D455 是RealSense D400系列的一部分&#xff0c;这个系列的设备以其高精度和可靠性而闻名。D455相比于之前的型号&#xff08;如D415和D435&#xff09;&#xff0c;提供了更远的感知范围和更高的精度。 二、使用代码 我们先定义一下相关的函数…

鸿蒙OS初识

学习官网&#xff1a;https://www.harmonyos.com/cn/develop 准备 注册&#xff0c;安装软件&#xff08;node:12, DevEco Studio&#xff09;&#xff1a; https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-0000001053582415#ZH-CN_TOP…

MFC3d立体按钮制作

1、本程序基于前期我的博客文章MFC用CButtonST类实现图片透明按钮(免费源码下载) 2、添加CeXDib.cpp CeXDib.h ShadeButtonST.cpp ShadeButtonST.h到项目文件夹下&#xff0c;和FileView中如图。 3、在ButtonShadeDlg.h中添加代码 #include "ShadeButtonST.h" #in…

Qml开发的两种方法

一.Qml开发的两种方法 1.Qt Creator 开发,手动编写qml代码 这种方法开发很方便&#xff0c;适合对qml语言非常熟悉的开发人员。 2.用Qt Design Studio 设计qml界面 这种方法更适合对qml不太熟悉的人&#xff0c;可以实现qml控件的拖拉拽&#xff0c;类似与widget界面开发&…

【原型模式】详解

一.概念 原型模式是一种创建型设计模式&#xff0c;它的主要思想是通过复制现有对象来创建新对象&#xff0c;而不是通过实例化一个类来创建。在原型模式中&#xff0c;我们称被复制的对象为原型&#xff08;Prototype&#xff09;&#xff0c;新创建的对象为克隆体&#xff0…

用户画像知识点补充——多数据源

引入 针对用户画像项目来说&#xff08;产品&#xff09;必须要支持从多种数据源加载业务数据&#xff0c;构建用户标签。 在之前的标签模型开发中&#xff0c;主要是为了简化开发复杂度&#xff0c;业务数据统一存储到HBase表中。 数据源包含如下几个方面&#xff1a; 存储H…

【应用层】 DNS 域名协议解析

文章目录 DNS(Domain Name System)出现及演化 ⏳DNS 概括&#x1f50d;DNS定义DNS 作用 DNS工作原理⚙️域名解析DNS解析的详细工作流程 DNS域名解析方式&#x1f504;静态DNS域名解析动态DNS域名解析 DNS域名解析过程的深入分析 &#x1f9d0;递归查询迭代查询 公共DNS服务器的…

STC8增强型单片机进阶开发--LED呼吸灯(PWM)

知不足而奋进 望远山而前行 文章目录 目录 文章目录 前言 目标 内容 PWM基础概念 STC8H芯片 PWMA应用 PWM配置详解 周期 占空比 模式 使能PWM 引脚配置 EAXSFR扩展寄存器 总结 前言 学习PWM&#xff08;脉宽调制&#xff09;是探索数字信号转模拟信号的重要一步&#xff0c;尤…

ad18学习笔记21:焊盘设置Paste Mask Expansion(锡膏层延伸)

在pcb上放置焊盘的时候&#xff0c;可以对焊盘进行设置&#xff0c;可以用默认的规则&#xff0c;可以用自定义的规则&#xff0c;网上很少看到自定义的规则怎么用。 参考了官方的说明文档&#xff0c;我只是稍微补充了一下 paste mask与solder mask有哪些区别_paste mask与s…

终于更新了!时隔一年niushop多商户b2b2c的新补丁v5.0.2终于发布了,一起看看有啥新变化

注意这是最新版的V5.02_多商户V5.0.2版本更新说明 瞧瞧更新了什么内容&#xff0c; 优化功能 优化手机号、身份证等常用验证规则&#xff0c;全局化处理优化商品列表接口查询速度 修复功能修复系统内部分图片上传功能调用接口跨端口问题修复总后台和商家后台订单管理搜索标签在…

一文彻底讲透 PyTorch

节前&#xff0c;我们组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、今年参加社招和校招面试的同学。 针对大模型技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备面试攻略、面试常考点等热门话题进行了深入的讨论。 汇总合集…

JQC-3FF-S-Z 继电器模块使用(arduino)

前言 继电器模块可以控制电流的接通和非接通状态&#xff0c;和开关一样。实际上是用小电流去控制大电流运作的一种“自动开关” 本文只是简单使用继电器模块做一个 led 点亮和熄灭的案例&#xff0c;结合案例可以和 nodemcu 等板子结合做出远程控制开关。 材料准备 杜邦线…

无限可能LangChain——构建一个简单的LLM应用程序

在本快速入门中&#xff0c;我们将向您展示如何构建一个简单的LLM应用程序。该应用程序将文本从英语翻译成另一种语言。这是一个相对简单的LLM应用程序——它只是一个LLM调用加上一些提示。尽管如此&#xff0c;这仍然是开始使用LangChain的好方法——只需一些提示和一个LLM调用…

小波相干性显著性检验(MATLAB R2018A)

交叉小波常被用于检测不同信号之间的相关性&#xff0c;其在时频域建立了不同信号之间的联系。对于两个时域信号&#xff0c;其交叉小波变换和交叉小波尺度谱如下&#xff1a; 以轴承振动信号为例&#xff0c;利用正常轴承与故障轴承的振动信号、故障轴承和故障轴承的振动信号分…

【JavaEE进阶】——Mybatis操作数据库(使用注解和XML方式)

目录 &#x1f6a9;三层架构 &#x1f388;JDBC操作回顾 &#x1f6a9;什么是MyBatis &#x1f6a9;MyBatis⼊⻔ &#x1f388;准备工作 &#x1f4dd;创建⼯程 &#x1f4dd;数据准备 &#x1f388;配置数据库连接字符串 &#x1f388;写持久层代码 &#x1f388;单…

插入排序(直接插入排序、折半插入排序、希尔排序)的性能分析

目录 前言 插入排序 直接插入排序性能分析 折半插入排序性能分析 希尔排序性能分析 前言 本篇文章主要是总结插入排序的性能分析&#xff0c;具体的概念、算法、排序过程&#xff0c;我前面的文章有写&#xff0c;在这里就不再过多赘述了。 插入排序 插入排序是一种简单直…

如何从Windows的硬盘中恢复丢失或删除的照片

你有没有不小心删除了一张你再也找不回来的重要照片&#xff1f;如果是您的公司或家庭照片、婚礼或童年回忆&#xff0c;或亲人的照片怎么办&#xff1f; 根据我们的经验&#xff0c;用户通常会在清理计算机的存储/速度时遇到这样的事故&#xff0c;并最终删除包含重要图片的文…