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和reactive
	import {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,并传c2FMsg
		emit('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,并传c2FMsg
			emit('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 小结

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

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

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

相关文章

【TB作品】MSP430F5529,单片机,打地鼠游戏

功能 针对这块开发板做了一个打地鼠游戏&#xff1a; 1 给单片机上电后&#xff0c;初始化显示界面&#xff0c;显示出分数和等级。 2 游戏是一轮一轮进行的&#xff0c;每一轮会以50%几率点亮板子上的五个小灯&#xff0c;表示地鼠露头需要打了。 3 一轮游戏开始后&#xff…

STM32作业设计

目录 STM32作业设计 STM32作业实现(一)串口通信 STM32作业实现(二)串口控制led STM32作业实现(三)串口控制有源蜂鸣器 STM32作业实现(四)光敏传感器 STM32作业实现(五)温湿度传感器dht11 STM32作业实现(六)闪存保存数据 STM32作业实现(七)OLED显示数据 STM32作业实现(八)触摸按…

PKG系统安装包及IPSW固件下载(MacOS 11-14)11.7.10/12.7.1/13.6.

MacOS 14 Sonoma&#xff0c;为提高生产力和创造力带来了全新的功能&#xff0c;有了更多使用小部件和令人惊叹的新屏幕保护程序进行个性化设置的方法&#xff0c;对Safari浏览器和视频会议进行了重大更新&#xff0c;以及优化的游戏体验——Mac体验比以往任何时候都更好。 下载…

关于linux程序的查看、前台运行、后台运行、杀死的管理操作。

前言 在Linux中&#xff0c; 程序&#xff08;program&#xff09;是放在磁盘上的程序&#xff0c;是不会执行的。 进程&#xff08;process&#xff09;是程序被触发&#xff0c;从而加载到内存中的&#xff0c;会被CPU随机执行。 Linux中&#xff0c;有非常多的进程在实时运…

绿联 安装memcached容器 - 一个开源的高性能分布式内存对象缓存系统

绿联 安装memcached容器 - 一个开源的高性能分布式内存对象缓存系统 1、镜像 memcached:latest 2、安装 2.1、基础设置 重启策略&#xff1a;容器退出时总是重启容器。 2.2、网络 网络选择桥接(bridge)。 2.3、端口设置 容器端口11211固定不变&#xff0c;本地端口若未被…

STAT315 Week 8 广义线性混合模型(GLMMs)

正如我们使用 LMM 对具有相关观测值的正态数据进行建模一样&#xff0c;我们可以使用 GLMM 对非正态分布且具有相关观测值的数据进行建模。 响应变量通常是离散的或明显非正态的。 GLMM 允许响应数据来自指数族的任何其他分布&#xff0c;包括最常见的二项分布和泊松分布。因此…

第五维度【百度之星】/二分

第五维度 二分 思路&#xff1a;看到题目是尽可能晚的情况下最早就应该想到贪心。 #include<bits/stdc.h> using namespace std; typedef long long ll; ll a[100005],b[100005]; ll n,m; bool check(ll t) {ll res0,big0;for(ll i0;i<n;i) {if(a[i]>t) continue…

基于MingGW64 GCC编译Windows平台上的 libuvc

安装cmake 打开cmake官网 https://cmake.org/download/&#xff0c;下载安装包&#xff1a; 安装时选择将cmake加到系统环境变量里。安装完成后在新的CMD命令窗口执行cmake --version可看到输出&#xff1a; D:\>cmake --version cmake version 3.29.3 CMake suite mainta…

牛客网刷题 | BC108 反斜线形图案

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 KiKi学习了循环&am…

git远程仓库限额的解决方法——大文件瘦身

Git作为世界上最优秀的分布式版本控制工具&#xff0c;也是优秀的文件管理工具&#xff0c;它赋予了项目成员对项目进行远程协同开发能力&#xff0c;因此受到越来越多的行业从业人员的喜爱。很多优秀的项目管理平台&#xff0c;比如国内的Gitee&#xff0c;国外的Github&#…

列表和列表项

一、列表和列表项简介 列表是 FreeRTOS 中的一个数据结构&#xff0c;列表被用来跟踪 FreeRTOS中的任务&#xff08;任务当前的状态&#xff09;&#xff0c;列表项就是存放在列表中的项目 列表相当于链表&#xff0c;列表项相当于节点&#xff0c;FreeRTOS 中的列表是一个双向…

Qt各发布版本介绍与选择

一.Qt各个主要版本介绍 1.Qt4 Qt4的第一个版本是Qt 4.0&#xff0c;发布于2005年6月1日。 Qt 4的最后一个版本是Qt 4.8.7&#xff0c;发布时间是2015年6月10日。 2.Qt5 &#xff08;1&#xff09;Qt5的第一个版本是Qt 5.0&#xff0c;发布于2012年12月19日。 &#xff08;2&…

575. 分糖果

题目 Alice 有 n 枚糖&#xff0c;其中第 i 枚糖的类型为 candyType[i]。Alice 注意到她的体重正在增长&#xff0c;所以前去拜访了一位医生。 医生建议 Alice 要少摄入糖分&#xff0c;只吃掉她所有糖的 n / 2 即可&#xff08;n 是一个偶数&#xff09;。Alice 非常喜欢这些…

LabVIEW版本控制

LabVIEW作为一种流行的图形化编程环境&#xff0c;在软件开发中广泛应用。有效地管理版本控制对于确保软件的可靠性和可维护性至关重要。LabVIEW提供了多种方式来管理VI和应用程序的修订历史&#xff0c;以满足不同规模和复杂度的项目需求。 LabVIEW中的VI修订历史 LabVIEW内置…

低代码选型要注意什么问题?

低代码选型时&#xff0c;确实需要从多个角度综合考虑&#xff0c;以下是根据您给出的角度进行的分析和建议&#xff1a; 公司的人才资源&#xff1a; 评估团队中是否有具备编程能力的开发人员&#xff0c;以确保能够充分利用低代码平台的高级功能和进行必要的定制开发。考察实…

11.2.0.3RAC 备份集恢复为单实例11.2.0.4_法一:rman备份恢复

关键步骤&#xff1a; 1、移动硬盘格式化成Linux可以识别的文件系统&#xff0c;mount到备份目录&#xff0c;开始rman备份&#xff0c;备份完成后&#xff0c;插到目标服务器挂载&#xff0c; 2、恢复参数文件nomount库&#xff0c;恢复控制文件mount库&#xff0c;restore …

工业互联网数字中台建设方案(ppt)

工业互联网数字中台整体解决方案&#xff08;ppt原件&#xff09; 1、工业数字中台的价值 2、数字化中台的特点 3、数字化中台方案介绍 软件项目相关全套精华资料包获取方式①&#xff1a;点我获取 获取方式②&#xff1a;本文末个人名片直接获取。 软件资料清单列表部分文档…

pyopengl 立方体 正投影,透视投影

目录 顶点和线的方式 划线的方式实现: 顶点和线的方式 import numpy as np from PyQt5 import QtWidgets from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton from OpenGL.GL import * from OpenGL.GLU import * import sys…

Jupyter Notebook快速搭建

Jupyter Notebook why Jupyter Notebook Jupyter Notebook 是一个开源的 Web 应用程序&#xff0c;允许你创建和分享包含实时代码、方程、可视化和解释性文本的文档。其应用包括&#xff1a;数据清洗和转换、数值模拟、统计建模、数据可视化、机器学习等等。 Jupyter Notebo…

springboot+vue+mybatis超市管理-简单版+PPT+论文+讲解+售后

使用旧方法对超市信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在超市信息的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。 这次开发的小型超市管理系统有管理员&…