Vue3(五):组件通信详解(九种方法)

主要有九种方法,以下是详细解释及使用方法:

1.props

props实现父子间的通信,是使用频率最高的。

(1)父传子:属性值是非函数。

以Father.vue和Child.vue 为例。

父组件中,引入子组件并给子组件绑定一个car参数,

子组件中,使用defineProps([''])接收,在template中,可以直接使用car

(2)子传父:属性值是函数

其实子传父前提父亲先给子传递一个函数,子接收到了再传给父。

比如我要把儿子的toy传给父亲,那么就需要在父中先定义一个getToy函数,用:sendToy=''getToy"传给子,然后子再去调用sendToy。

2.自定义事件emit

1. 概述:

自定义事件常用于:子 => 父

2. 原生Dom事件、自定义事件

(1)原生Dom事件:

  - 事件名是特定的(click、dbdlick、change等等)

  - 事件对象`$event`: 是包含事件相关信息的对象(`pageX`、`pageY`、`target`、`keyCode`)

(2)自定义事件:

  - 事件名是任意名称

  - <strong style="color:red">事件对象`$event`: 是调用`emit`时所提供的数据,可以是任意类型!!!</strong >

  1. vue2中 @click是自定义事件,可以通过.native修饰符变为原生DOM事件。

  2. 在vue3中@click是原生DOM事件

  3. `$event是事件对象

3. 例如:

子组件传给父亲toy,就可以这样做:父组件自定义一个send-toy方法,然后子组件使用defineEmits接收,再用emit传给父亲,之后父亲利用send-toy的回调保存传输过来的toy

3.mitt

1.概述

与消息订阅与发布(`pubsub`)功能类似,可以实现任意组件间通信

就是只要任意两个组件能够摸到emitter,就能实现通信。

2.使用mitt

(1)安装mitt

npm i mitt

(2)新建文件:src\utils\emitter.ts

// 引入mitt 
import mitt from "mitt";// 创建emitter
const emitter = mitt()/*// 绑定事件emitter.on('abc',(value)=>{console.log('abc事件被触发',value)})emitter.on('xyz',(value)=>{console.log('xyz事件被触发',value)})setInterval(() => {// 触发事件emitter.emit('abc',666)emitter.emit('xyz',777)}, 1000);setTimeout(() => {// 清理事件emitter.all.clear()}, 3000); 
*/// 创建并暴露mitt
export default emitter

3.使用

 emit触发,on绑定。

比如弟弟child2想要哥哥child1的玩具 ,那child2要用emitter.on绑定事件,然后child1用emitter.emit触发事件。

(注意:这里最好用onUnmounted解绑一下事件,如果有一天这个组件被卸载了,但是他化存在这个关系,就会对内存不友好) 

4.v-model

1.本质

实现父↔子间通信

其实一般很少使用v-model,但是在UI组件库中会大量使用v-model.

2.使用

(1)v-model用在html标签上

v-model本质其实是value和input的结合使用 

<!-- v-model用在html标签上 --><!-- <input type="text" v-model="username"> --><input type="text" :value="username" @input="username = (<HTMLInputElement>$event.target).value"><!-- <HTMLInputElement>是说明$event.target是一个html中输入类型的元素 -->

 可以实现双向绑定

(2)v-model用在组件标签

 只需要在组件标签中v-model="username",然后引入UI组件库。

组件标签上的`v-model`的本质:`:moldeValue` + `update:modelValue`事件。

组件标签中: 

<!-- 组件标签上使用v-model指令 --><AtguiguInput v-model="userName"/><!-- 组件标签上v-model的本质 --><AtguiguInput :modelValue="userName" @update:model-value="userName = $event"/>

 UI组件库中:

<template><div class="box"><!--将接收的value值赋给input元素的value属性,目的是:为了呈现数据 --><!--给input元素绑定原生input事件,触发input事件时,进而触发update:model-value事件--><input type="text" :value="modelValue" @input="emit('update:model-value',$event.target.value)"></div></template><script setup lang="ts" name="AtguiguInput">// 接收propsdefineProps(['modelValue'])// 声明事件const emit = defineEmits(['update:model-value'])</script>

(3) 修改modelValue

 可以修改modelValue的话,就意味着可以在组件标签上使用多个v-model.

多个v-model 

5.$attrs

1. 概述

`$attrs`用于实现当前组件的父组件,向当前组件的子组件通信(祖孙通信)。

2. 具体说明

`$attrs`是一个对象,包含所有父组件传入的标签属性。

   >  注意:`$attrs`会自动排除`props`中声明的属性(可以认为声明过的 `props` 被子组件自己“消费”了)

3.使用

先来了解一下attrs 

首先父向子传递多个响应式数据,但是子只接受一个a,那么剩下的都去哪里了呢。其实在attrs中存着,我们可以用$attrs看到

(1)祖传孙: 

 假如上述父子传递时,子不接收呢?而是用v-bind传给孙组件呢?

那么在孙组件中就可以用defineProps接收,并呈现出来。

这样就实现了祖向孙通信 

(2)孙传祖

在祖里面定义有一个方法

并把方法也传给子

<Child :a="a" :b="b" :c="c" :d="d" v-bind="{x:100,y:200}" :updateA="updateA"/>

 而子中依旧是这样:

<GrandChild v-bind="$attrs"/>

那么孙中只要接收到了方法,就可以绑定一个点击事件,把自己的定义的数字6传给祖的value,实现孙传祖。

6.$refs、$parent 

1. 概述:

$refs`用于 :父→子

$parent`用于:子→父

2.原理如下

3.使用

(1)ref

 先来看一下用ref是怎么修改的。首先用ref给Child1打个标识c1,然后配置一个修改方法changeToy

之后在child1中配置difineExpose就可以了,这样父就能点击修改子的玩具。实现父到子通信。

// 把数据交给外部defineExpose({toy,book})

 同理如果父亲想要修改child2的数据也同理。

(2)$refs

在父组件中用如下写法可以获取所有子组件的实例对象 

<button @click="getAllChild($refs)">获取所有子组件的实例对象</button>

 如图所示:可以获取

那么就可以利用refs修改所有子组件共同想修改的内容,例如修改所有子组件的玩具数量。 

记得在所有子组件里面配置defineExpose

// 把数据交给外部defineExpose({toy,book})

 (3)$parent

通过$parent可以看到父组件的实例对象 。这样可以通过在子组件中使用$parent并配置方法,从而修改父组件数据。实现子向父通信。

千万不要忘了在父组件中配置defineExpose

// 向外部提供数据defineExpose({house})

7.provide、inject

1.概述

实现祖孙组件直接通信

2. 具体使用

   * 在祖先组件中通过`provide`配置向后代组件提供数据

   * 在后代组件中通过`inject`配置来声明接收数据

3.例如

(1)祖传孙

例如把爷爷有的钱和车子都传给孙,应该怎么做呢?

在父组件中先从vue中import引入provide ,而后使用provide向后代提供数据

provide('名字',值)    需要注意的是这个值后面不要.value,这样会丢失响应式

 

在后代组件中,先import引入inject,而后使用inject接收数据。

需要注意的是,inject('名字','默认值')这2个参数 一个是名字一个是默认值,如果不写默认值的话,上面的car.brand和car.price就会报错。

(2)孙传祖

比如孙子华爷爷的钱。在孙组件里面点击一下按钮就能修改爷爷的钱。

首先在祖组件里面定义一个方法,在provide里面传的是money的值和这个方法给孙组件

那么在孙组件里面可以把传过来的值和方法 利用解构赋值,然后再添加一个按钮绑定这个方法,并传数据。就实现了孙传祖。

8.pinia

详见上一节:Vue3(四):Pinia-CSDN博客

9.slot插槽

假如要实现这样一个效果:

  

1.默认插槽

slot里面是默认内容,如果没有要插进来的内容,就会显示默认内容

//父组件中:<Category title="今日热门游戏"><ul><li v-for="g in games" :key="g.id">{{ g.name }}</li></ul></Category>
//子组件中:<template><div class="item"><h3>{{ title }}</h3><!-- 默认插槽 --><slot></slot></div></template>

2.具名插槽

在子组件标签里面把需要传递的内容使用template标签包括,用v-slot命名,也可以用#命名。 子组件slot中用相应的name="xxx"

父组件中:<Category title="今日热门游戏"><template v-slot:s1><ul><li v-for="g in games" :key="g.id">{{ g.name }}</li></ul></template><template #s2><a href="">更多</a></template></Category>
子组件中:<template><div class="item"><h3>{{ title }}</h3><slot name="s1"></slot><slot name="s2"></slot></div></template>

3.作用域插槽

像下面这样,父组件拿games会报错,因为这时候父组件是拿不到子组件的games的,涉及到一个作用域的内容。 

对于作用域插槽的解释:可以这样理解 

语法及使用:

第一种是使用v-slot="params",意思是吧template里面的内容放在默认插槽里面

第二种是也可以使用命名的方式,因为slot有默认的命名,default,所以可以用#default

10.总结

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

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

相关文章

34、链表-合并K个升序链表

思路 1、直接全部放入集合中&#xff0c;然后排序&#xff0c;在进行构造节点返回 2、使用归并排序的方式&#xff0c;两两排序合并&#xff0c;最后合并大的。 3、第三中思路就比较巧妙了&#xff0c;可以使用小根堆&#xff0c;每次弹出堆顶&#xff0c;最小值&#xff0c…

【计算机网络】http协议的原理与应用,https是如何保证安全传输的

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

基于 RT-Thread 的 CMUX 串口多路复用的详细使用

一、CMUX 软件包的介绍 CMUX&#xff08;Connection Multiplexing &#xff09;&#xff0c;即连接&#xff08;串口&#xff09;多路复用&#xff0c;其功能主要在一个真实的物理通道上虚拟多个通道&#xff0c;每个虚拟通道上的连接和数据通讯可独立进行。  CMUX 软件包常用…

DRF ModelSerializer序列化类

ModelSerializer序列化类 【0】准备 模型表创建 from django.db import modelsclass Book(models.Model):name models.CharField(max_length64, verbose_name书名)price models.DecimalField(max_digits6, decimal_places2, verbose_name价格)publish models.ForeignKey(…

【C++打怪之路】-- C++开篇

&#x1f308; 个人主页&#xff1a;白子寰 &#x1f525; 分类专栏&#xff1a;C打怪之路&#xff0c;python从入门到精通&#xff0c;魔法指针&#xff0c;进阶C&#xff0c;C语言&#xff0c;C语言题集&#xff0c;C语言实现游戏&#x1f448; 希望得到您的订阅和支持~ &…

vue-cli2 与vue-cli3,vue2与vue3 初始化项目,本地vue项目,详细解析区别(2024-04-19)

目录 1、区别&#xff08;vue-cli2 与 vue-cli3 &#xff09; 2、例子1&#xff08;vue2项目&#xff09; 2.1 版本与命令行 2.2 项目本地截图 2.3 项目文件解析 &#xff08;1&#xff09;package.json 文件 &#xff08;2&#xff09;webpack.dev.conf.js文件 &#…

[大模型]Qwen-7B-hat Transformers 部署调用

Qwen-7B-hat Transformers 部署调用 环境准备 在autodl平台中租一个3090等24G显存的显卡机器&#xff0c;如下图所示镜像选择PyTorch–>2.0.0–>3.8(ubuntu20.04)–>11.8 接下来打开刚刚租用服务器的JupyterLab&#xff0c;并且打开其中的终端开始环境配置、模型下…

NLP自然语言处理_序章

开一个新篇章&#xff0c;立一个flag&#xff0c;用一段时间来学习一下NLP&#xff0c;涨涨见识。 准备以B站 机器学习算法到transformer神经网络模型应用视频作为入门&#xff0c;此分类专门用于记录学习过程中的知识点以备自用。 一、何为NLP自然语言处理&#xff1f; NLP…

查看linux的主机配置脚本

废话不说 直接上指令 curl -Lso- bench.sh | bash 等待后&#xff0c;结果如图&#xff1a; 使用后没有问题&#xff0c;看情况使用 出事概不负责 介意勿用&#xff01;&#xff01;&#xff01;

RabbitMQ 各种通信模式的Python实现

一、RabbitMQ 原理 1、基本原理 RabbitMQ是流行的开源消息队列系统&#xff0c;用erlang语言开发。RabbitMQ是AMQP&#xff08;高级消息队列协议&#xff09;的标准实现。支持多种客户端&#xff0c;如&#xff1a;Python、Java、Javascript、C#、C/C,Go等&#xff0c;支持AJ…

使用yolov8 进行实例分割训练

1、基于windows 的ISAM标注 直接下载安装包&#xff0c;解压后即可使用 链接&#xff1a;https://pan.baidu.com/s/1u_6jk-7sj4CUK1DC0fDEXQ 提取码&#xff1a;c780 2、标注结果转yolo格式 通过ISAM标注后的json文件路径 原始json格式如下&#xff1a; ISAM.json 转 yolo.…

Leetcode算法训练日记 | day30

一、重新安排行程 1.题目 Leetcode&#xff1a;第 332 题 给你一份航线列表 tickets &#xff0c;其中 tickets[i] [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。 所有这些机票都属于一个从 JFK&#xff08;肯尼迪国际机场&#xff09;出发…

深入刨析 mysql 底层索引结构B+树

文章目录 前言一、什么是索引&#xff1f;二、不同索引结构对比2.1 二叉树2.2 平衡二叉树2.3 B-树2.4 B树 三、mysql 的索引3.1 聚簇索引3.2 非聚簇索引 前言 很多人看过mysql索引的介绍&#xff1a;hash表、B-树、B树、聚簇索引、主键索引、唯一索引、辅助索引、二级索引、联…

【Hadoop大数据技术】——Sqoop数据迁移(学习笔记)

&#x1f4d6; 前言&#xff1a;在实际开发中&#xff0c;有时候需要将HDFS或Hive上的数据导出到传统关系型数据库中&#xff08;如MySQL、Oracle等&#xff09;&#xff0c;或者将传统关系型数据库中的数据导入到HDFS或Hive上&#xff0c;如果通过人工手动进行数据迁移的话&am…

怎么看自己是不是公网IP?

当我们需要进行网络连接或者网络配置的时候&#xff0c;经常会遇到需要知道自己是否拥有公网IP的情况。公网IP是全球唯一的IP地址&#xff0c;在互联网上可直接访问和被访问&#xff0c;而私有IP则是在本地网络中使用&#xff0c;无法从互联网上直接访问。我们将介绍如何查看自…

笔记-----BFS宽度优先搜索

对于BFS&#xff1a;宽搜第一次搜到就是最小值&#xff0c;并且基于迭代&#xff0c;不会爆栈。 Flood Fill 模型 如果直译的话就是&#xff1a;洪水覆盖&#xff0c;意思就是像是从一个点一圈圈的往外扩散&#xff0c;如果遇见能够连通的就扩散&#xff0c;如果遇见无法联通的…

TCP三次握手,但通俗理解

如何用通俗的语言来解释TCP&#xff08;传输控制协议&#xff09;的三次握手过程&#xff1f; 想象一下你正在和朋友电话沟通&#xff0c;但你们之间不是心灵感应&#xff0c;而是需要通过清晰地听到对方的声音来确认通话质量良好。TCP三次握手就像是在电话拨通之前&#xff0…

爱普生发布一款16位MCU产品用于大电流LED驱动

精工爱普生发布一款内置Flash存储器的16位微控制器S1C17M13 该新品可以提供最大56mA的驱动电流用于驱动发光二极管(LED) 以往爱普生的微处理器大多继承了液晶驱动器电路&#xff0c;但近来随着工业自动化和家用设备使用7段LED显示的数量大幅增加&#xff0c;爱普生也推出了对应…

k8s:通过nodeSelector将pod调度到含有指定标签的结点上

一、查看node,并给node打标签 二、在资源清单文件中配置nodeSelector来指定要往满足哪个标签条件的结点进行调度 apiVersion: v1 kind: Pod metadata:name: probe-tcp spec:containers:- name: nginximage: nginxlivenessProbe:initialDelaySeconds: 5timeoutSeconds: 5tcpSo…

宝塔面板使用docker+nginx+gunicorn部署Django项目实战教程

第一步&#xff1a;创建Django项目 使用pip install django安装创建django项目的依赖在电脑某个根目录下执行django-admin startproject app创建一个名为app的Django项目。目录结构如下: ├── app │ ├── init.py │ ├── asgi.py │ ├── settings.py │ ├── url…