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

本文主要是介绍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 小结

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

这篇关于Vue3中的常见组件通信之props和自定义事件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

从入门到精通详解LangChain加载HTML内容的全攻略

《从入门到精通详解LangChain加载HTML内容的全攻略》这篇文章主要为大家详细介绍了如何用LangChain优雅地处理HTML内容,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录引言:当大语言模型遇见html一、HTML加载器为什么需要专门的HTML加载器核心加载器对比表二

Python实现MQTT通信的示例代码

《Python实现MQTT通信的示例代码》本文主要介绍了Python实现MQTT通信的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 安装paho-mqtt库‌2. 搭建MQTT代理服务器(Broker)‌‌3. pytho

MySQL深分页进行性能优化的常见方法

《MySQL深分页进行性能优化的常见方法》在Web应用中,分页查询是数据库操作中的常见需求,然而,在面对大型数据集时,深分页(deeppagination)却成为了性能优化的一个挑战,在本文中,我们将... 目录引言:深分页,真的只是“翻页慢”那么简单吗?一、背景介绍二、深分页的性能问题三、业务场景分析四、

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

Java 方法重载Overload常见误区及注意事项

《Java方法重载Overload常见误区及注意事项》Java方法重载允许同一类中同名方法通过参数类型、数量、顺序差异实现功能扩展,提升代码灵活性,核心条件为参数列表不同,不涉及返回类型、访问修饰符... 目录Java 方法重载(Overload)详解一、方法重载的核心条件二、构成方法重载的具体情况三、不构

SQL中如何添加数据(常见方法及示例)

《SQL中如何添加数据(常见方法及示例)》SQL全称为StructuredQueryLanguage,是一种用于管理关系数据库的标准编程语言,下面给大家介绍SQL中如何添加数据,感兴趣的朋友一起看看吧... 目录在mysql中,有多种方法可以添加数据。以下是一些常见的方法及其示例。1. 使用INSERT I

Python中反转字符串的常见方法小结

《Python中反转字符串的常见方法小结》在Python中,字符串对象没有内置的反转方法,然而,在实际开发中,我们经常会遇到需要反转字符串的场景,比如处理回文字符串、文本加密等,因此,掌握如何在Pyt... 目录python中反转字符串的方法技术背景实现步骤1. 使用切片2. 使用 reversed() 函

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字

Python中win32包的安装及常见用途介绍

《Python中win32包的安装及常见用途介绍》在Windows环境下,PythonWin32模块通常随Python安装包一起安装,:本文主要介绍Python中win32包的安装及常见用途的相关... 目录前言主要组件安装方法常见用途1. 操作Windows注册表2. 操作Windows服务3. 窗口操作

ModelMapper基本使用和常见场景示例详解

《ModelMapper基本使用和常见场景示例详解》ModelMapper是Java对象映射库,支持自动映射、自定义规则、集合转换及高级配置(如匹配策略、转换器),可集成SpringBoot,减少样板... 目录1. 添加依赖2. 基本用法示例:简单对象映射3. 自定义映射规则4. 集合映射5. 高级配置匹