07-Vue技术栈之(组件之间的通信方式)

news2024/12/22 23:22:35

目录

  • 1、组件的自定义事件
    • 1.1 绑定自定义事件:
      • 1.1.1 第一种方式
      • 1.1.2 第二种方式
      • 1.1.3 自定义事件只触发一次
    • 1.2 解绑自定义事件
    • 1.3绑定原生DOM事件
    • 1.4 总结
  • 2、全局事件总线(GlobalEventBus)
    • 2.1 应用全局事件总线
  • 3、 消息订阅与发布(pubsub)
    • 3.1 应用消息订阅与发布

前言:
组件之间通信的方式有很多种,比如props自定义事件全局事件总线消息订阅与发布父链与子组件索引插槽Vuex等都可以实现组件之间的通信。在这里我将介绍以下三种通信方式。

1、组件的自定义事件

  • 它是一种组件间通信的方式,适用于:子组件 ===> 父组件
  • 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。

1.1 绑定自定义事件:

1.1.1 第一种方式

  • 在父组件中:<Demo @dome="test"/><Demo v-on:dome="test"/>
  • 触发自定义事件:this.$emit('dome',数据)

代码示例:

app组件

<template>
  <div>
    <h1 class="title">你好啊</h1>
    <Student @dome="test" />
  </div>
</template>

<script>
import Student from "./components/Student";
export default {
  name: "App",
  components: { Student },
  methods: {
    test() {
      console.log("我被触发了");
    },
  },
};
</script>

<style scoped>
</style>

子组件student

<template>
  <div class="demo">
    <button @click="domes">点我触发</button>
  </div>
</template>

<script>
export default {
  name: "Student",
  methods: {
    domes() {
      this.$emit("dome");
    },
  },
};
</script>

<style scoped>
</style>

1.1.2 第二种方式

在父组件中:

 	<Demo ref="xxx"/>
      ......
      mounted(){
         this.$refs.xxx.$on('demo',this.test)
      }

代码示例:

app组件

<template>
  <div>
    <h1 class="title">你好啊</h1>
    <!-- <Student @dome.once="test" /> -->
    <Student ref="student" />
  </div>
</template>

<script>
import Student from "./components/Student";
export default {
  name: "App",
  components: { Student },
  methods: {
    test() {
      console.log("我被调用了");
    },
  },
  mounted() {
    this.$refs.student.$on("dome", this.test);
  },
};
</script>

<style scoped>
</style>

子组件student

<template>
  <div class="demo">
    <button @click="domes">点我触发</button>
  </div>
</template>

<script>
export default {
  name: "Student",
  methods: {
    domes() {
      this.$emit("dome");
    },
  },
};
</script>

<style scoped>
</style>

注意:通过this.$refs.xxx.$on('dome',回调)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!

代码示例:

  mounted() {
    this.$refs.student.$on("dome", function() {
		 console.log(this);
		 this指向子组件student
		 将普通函数换成箭头函数,this指向就还是原来的app组件
	});
  },

1.1.3 自定义事件只触发一次

若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。
代码示例:

  1. once修饰符使用方法

代码示例:
app组件

<template>
  <div>
    <h1 class="title">你好啊</h1>
    <Student @dome.once="test" /><!--绑定自定义事件,一次性 -->
    <!-- <Student ref="student" /> -->
  </div>
</template>

<script>
import Student from "./components/Student";
export default {
  name: "App",
  components: { Student },
  methods: {
    test() {
      console.log("我被调用了");
    },
  },
 /*  mounted() {
    this.$refs.student.$on("dome", this.test);
  }, */
};
</script>

<style scoped>
</style>

  1. $once使用方法

代码示例:
app组件

<template>
  <div>
    <h1 class="title">你好啊</h1>
    <!-- <Student @dome.once="test" /> -->
    <Student ref="student" />
  </div>
</template>

<script>
import Student from "./components/Student";
export default {
  name: "App",
  components: { Student },
  methods: {
    test() {
      console.log("我被调用了");
    },
  },
  mounted() {
    this.$refs.student.$once("dome", this.test);//绑定自定义事件(一次性)
  },
};
</script>

<style scoped>
</style>

1.2 解绑自定义事件

  • 解绑自定义事件通过this.$off('atguigu')

代码示例:
app组件

<template>
  <div>
    <h1 class="title">你好啊</h1>
    <Student @dome="test" @dome2="test2"/>
    <!-- <Student ref="student" /> -->
  </div>
</template>

<script>
import Student from "./components/Student";
export default {
  name: "App",
  components: { Student },
  methods: {
    test() {
      console.log("我被调用了");
    },
    test2() {
      console.log("我是第二个事件");
    },
  },
  /* mounted() {
    this.$refs.student.$on("dome", this.test);
  }, */
};
</script>

<style scoped>
</style>

子student组件

<template>
  <div class="demo">
    <button @click="domes">点我触发</button>
	<button @click="unbind">点我解绑事件</button>
  </div>
</template>

<script>
export default {
  name: "Student",
  methods: {
    domes() {
      this.$emit("dome");
      this.$emit("dome2");//绑定多个自定义事件
    },
	unbind() {
		// this.$off("dome")//解绑一个自定义事件
		// this.$off(['dome','dome2'])//解绑多个自定义事件
		this.$off()//解绑所有的自定义事
	}
  },
};
</script>

<style scoped>
</style>

1.3绑定原生DOM事件

  • 组件上也可以绑定原生DOM事件,需要使用native修饰符。如果不加上native修饰符,Vue会默认将此事件当作自定义事件。

代码示例:

    <Student @click.native="xxx"/>

1.4 总结

  1. 一种组件间通信的方式,适用于:子组件 ===> 父组件

  2. 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。

  3. 绑定自定义事件:

    1. 第一种方式,在父组件中:<Demo @atguigu="test"/><Demo v-on:atguigu="test"/>

    2. 第二种方式,在父组件中:

      <Demo ref="demo"/>
      ......
      mounted(){
         this.$refs.xxx.$on('atguigu',this.test)
      }
      
    3. 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。

  4. 触发自定义事件:this.$emit('atguigu',数据)

  5. 解绑自定义事件this.$off('atguigu')

  6. 组件上也可以绑定原生DOM事件,需要使用native修饰符。

  7. 注意:通过this.$refs.xxx.$on('atguigu',回调)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!

2、全局事件总线(GlobalEventBus)

  • 一种组件间通信的方式,适用于任意组件间通信。

  • 安装全局事件总线:

    new Vue({
    	......
    	beforeCreate() {
    		Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
    	},
        ......
    }) 
    
  • 使用事件总线:

  • 接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。

    methods(){
      demo(data){......}
    }
    ......
    mounted() {
      this.$bus.$on('xxxx',this.demo)
    }
    
  • 提供数据:this.$bus.$emit('xxxx',数据)

  • 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件。

2.1 应用全局事件总线

  • 我们利用全局事件总线来完成一个兄弟间的通信

目录结构图:
在这里插入图片描述

代码示例:

main文件里面安装全局事件总线

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false

//创建vm
new Vue({
	el:'#app',
	render: h => h(App),
	beforeCreate() {
		Vue.prototype.$bus = this //安装全局事件总线
	},
})

没有涉及到和app组件通信,所有app组件正常编写即可

<template>
	<div class="app">
		<h1>{{msg}}</h1>
		<School/>
		<Student/>
	</div>
</template>

<script>
	import Student from './components/Student'
	import School from './components/School'

	export default {
		name:'App',
		components:{School,Student},
		data() {
			return {
				msg:'你好啊!',
			}
		}
	}
</script>

<style scoped>
	.app{
		background-color: gray;
		padding: 5px;
	}
</style>

由于我们将school组件作为接受数据方,所以我们要给school组件种的$bus绑定自定义事件,事件的回调留在school组件自身。

<template>
	<div class="school">
		<h2>学校名称:{{name}}</h2>
		<h2>学校地址:{{address}}</h2>
	</div>
</template>

<script>
	export default {
		name:'School',
		data() {
			return {
				name:'东方',
				address:'北京',
			}
		},
		mounted() {
			// console.log('School',this)
			this.$bus.$on('hello',(data)=>{
				console.log('我是School组件,收到了数据',data)
			})
		},
		beforeDestroy() {
			this.$bus.$off('hello')
		},
	}
</script>

<style scoped>
	.school{
		background-color: skyblue;
		padding: 5px;
	}
</style>

由于我们将student组件作为提供数据方,所以我们要在student组件中调用自定义事件

<template>
	<div class="student">
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
		<button @click="sendStudentName">把学生名给School组件</button>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				sex:'男',
			}
		},
		mounted() {
			// console.log('Student',this.x)
		},
		methods: {
			sendStudentName(){
				this.$bus.$emit('hello',this.name)
			}
		},
	}
</script>

<style lang="less" scoped>
	.student{
		background-color: pink;
		padding: 5px;
		margin-top: 30px;
	}
</style>

3、 消息订阅与发布(pubsub)

  1. 一种组件间通信的方式,适用于任意组件间通信。

  2. 使用步骤:

    1. 安装pubsub:npm i pubsub-js

    2. 引入: import pubsub from 'pubsub-js'

    3. 接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。

      methods(){
        demo(data){......}
      }
      ......
      mounted() {
        this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息
      }
      
    4. 提供数据:pubsub.publish('xxx',数据)

    5. 最好在beforeDestroy钩子中,用PubSub.unsubscribe(pid)去取消订阅。

3.1 应用消息订阅与发布

  • 将上面的全局事件总线案例应用消息订阅与发布的方法实现一下,整体思路是一样的。

目录结构图:

在这里插入图片描述

首先我们先要安装pubsub:npm i pubsub-js,然后在需要通信的组件中引入import pubsub from 'pubsub-js'这个包。

代码示例:
main文件

//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false

//创建vm
new Vue({
	el:'#app',
	render: h => h(App),
})

app组件

<template>
	<div class="app">
		<h1>{{msg}}</h1>
		<School/>
		<Student/>
	</div>
</template>

<script>
	import Student from './components/Student'
	import School from './components/School'

	export default {
		name:'App',
		components:{School,Student},

	data() {
		return {
				msg:'你好啊!',
			}
		}
	}
</script>

<style scoped>
	.app{
		background-color: gray;
		padding: 5px;
	}
</style>

school组件作为接受信息订阅方

<template>
	<div class="school">
		<h2>学校名称:{{name}}</h2>
		<h2>学校地址:{{address}}</h2>
	</div>
</template>

<script>
	import pubsub from 'pubsub-js'
	export default {
		name:'School',
		data() {
			return {
				name:'东方',
				address:'北京',
			}
		},
		mounted() {
			this.pubId = pubsub.subscribe('hello',(msgName,data)=>{
				console.log(this)
				// console.log('有人发布了hello消息,hello消息的回调执行了',msgName,data)
			})
		},
		beforeDestroy() {
			pubsub.unsubscribe(this.pubId)
		},
	}
</script>

<style scoped>
	.school{
		background-color: skyblue;
		padding: 5px;
	}
</style>

student组件作为发布信息方

<template>
	<div class="student">
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
		<button @click="sendStudentName">把学生名给School组件</button>
	</div>
</template>

<script>
	import pubsub from 'pubsub-js'
	export default {
		name:'Student',
		data() {
			return {
				name:'张三',
				sex:'男',
			}
		},
		mounted() {

		},
		methods: {
			sendStudentName(){
				pubsub.publish('hello',666)
			}
		},
	}
</script>

<style lang="less" scoped>
	.student{
		background-color: pink;
		padding: 5px;
		margin-top: 30px;
	}
</style>

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

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

相关文章

SwiftUI 极简实现文本摆动弹性动画

概览 SwiftUI 为我们来了界面设计和调试上的便利&#xff0c;只需几行代码我们就能实现一个不错的文本动画效果&#xff1a; 如上图所示&#xff0c;我们在 SwiftUI 中基本还没发力&#xff0c;就实现了文本摆动弹性动画。 这究竟是怎么做到的呢&#xff1f; 无需等待&#…

英文论文(sci)解读复现【NO.7】基于注意机制的改进YOLOv5s目标检测算法

此前出了目标检测算法改进专栏&#xff0c;但是对于应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读发表高水平学术期刊中的 SCI论文&a…

Loadrunner性能测试(一)

备注&#xff1a;电脑最好安装有IE浏览器 一、下载安装包 链接&#xff1a;https://pan.baidu.com/s/1f5Sw0QK5zrLCU1EbN01evg?pwdbite 提取码&#xff1a;bite 包含的文件有&#xff1a; 二、安装loadrunner 注意&#xff0c;以下教程仅展示需要特别注意的步骤&#x…

PHP学习笔记第一天

前言 作者简介&#xff1a;不知名白帽&#xff0c;网络安全学习者。 博客主页&#xff1a;不知名白帽的博客_CSDN博客-网络安全,CTF,内网渗透领域博主 网络安全交流社区&#xff1a;https://bbs.csdn.net/forums/angluoanquan 目录 PHP语法 基本的PHP语法 PHP的数据类型 PH…

Kubernetes 集群中某个节点出现 Error querying BIRD: unable to connect to BIRDv4 socket

1. 问题描述 Readiness probe failed: calico/node is not ready: BIRD is not ready: Error querying BIRD: unable to connect to BIRDv4 socket: dial unix /var/run/calico/bird.ctl: connect: connection refusedReadiness probe failed: 2023-05-04 22:13:23.706 [INFO]…

LiangGaRy-学习笔记-Day10

1、知识回顾 1.1、rpm依赖报错问题 rpm安装的时候&#xff0c;会有依赖报错rpm安装httpd服务&#xff0c;体现报错 #rpm安装httpd [rootNode1 ~]# rpm -ivh /mnt/cdrom/Packages/httpd-2.4.6-88.el7.centos.x86_64.rpm warning: /mnt/cdrom/Packages/httpd-2.4.6-88.el7.ce…

自己组装的电脑怎么用U盘安装系统操作教学

自己组装的电脑怎么用U盘安装系统操作教学分享。有的用户使用台式机的时候&#xff0c;会自己去进行硬件的组装&#xff0c;但是这样的电脑在安装好了之后&#xff0c;里面还没有系统&#xff0c;需要进行安装。如果你不知道怎么去安装&#xff0c;可以来看看以下的操作方法。 …

HummerRisk 使用教程:源码检测

HummerRisk 是开源的云原生安全平台&#xff0c;以非侵入的方式解决云原生环境的安全和治理问题。核心能力包括混合云的安全治理和云原生安全检测。 本文将介绍HummerRisk中「源码检测模块」的功能&#xff0c;包括如何配置项目源码&#xff0c;以及使用源码检测规则进行安全检…

香港top5功能完善炒期货投资app软件排名(最新评测)

选择一款合适的炒期货投资软件对于投资者来说至关重要。考虑软件稳定、交易流畅度、交易品种、数据可靠性、而且还要考虑费用等多方面因素。 首先&#xff0c;软件的稳定性很重要。选用稳定性高的软件可以避免如断电、手机或电脑死机等突发状况&#xff0c;保证交易安全顺畅。…

FreeRTOS 低功耗 Tickless 模式

文章目录 一、低功耗模式1. 睡眠(Sleep)模式2. 停止(Stop)模式3. 待机(Standby)模式 二、Tickless 模式详解1. 如何降低功耗&#xff1f;2. Tickless 具体实现 一、低功耗模式 STM32 本身就支持低功耗模式&#xff0c;有三种低功耗模式&#xff1a; ● 睡眠(Sleep)模式。 ● 停…

5_服务编排_docker-compose

服务编排之Docker Compose 微服务架构的应用系统中一般包含若干个微服务&#xff0c;每个微服务一般都会部署多个实例&#xff0c;如果每个微服务都要手动启停&#xff0c;维护的工作量会很大。 要从Dockerfile build image 或者去dockerhub拉取image 要创建多个container 要…

GB/T25915.1法规基本标准-洁净室按粒子浓度划分洁净

《GB/T25915.1-2021洁净室及相关受控环境 第一部分&#xff1a;按粒子浓度划分空气洁净度等级》等4部国家标准。 今天小编跟大家分享一下参编的GB/T25915.1-2021相关法规文件内容&#xff0c;帮助大家更好的了解相关法规知识。 1 范围 本文件规定了按空气中悬浮粒子浓度划分洁…

9:00进去,9:05就出来了,这问的也太···

从外包出来&#xff0c;没想到死在另一家厂子了。 自从加入这家公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到8月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资直降30%&#xff0c;顿时有吃不起饭的赶脚。 好在有个兄弟内推…

纯前端 根据目录解析word,拆分不同段落

前期回顾 两分钟学会 制作自己的浏览器 —— 并将 ChatGPT 接入_0.活在风浪里的博客-CSDN博客自定义浏览器&#xff0c;并集合ChatGPT&#xff0c;源码已公开https://blog.csdn.net/m0_57904695/article/details/130467253?spm1001.2014.3001.5501 &#x1f44d; 本文专栏…

Unity之OpenXR+XR Interaction Toolkit实现 监听VR手柄按键

一.前言 当我们接入XR Interaction Toolkit之后&#xff0c;我们可以很方便的做不同VR设备的适配&#xff0c;这在很大程度上提升了我们的开发效率&#xff0c;我们除了通过射线和物体交互之外&#xff0c;偶尔我们也会希望监听手柄上的部分按键的点击事件&#xff0c;今天我们…

网络安全大厂面试题合集

以下为网络安全各个方向涉及的面试题合集&#xff0c;星数越多代表问题出现的几率越大&#xff0c;祝各位都能找到满意的工作。 注&#xff1a;本套面试题&#xff0c;已整理成pdf文档&#xff0c;但内容还在持续更新中&#xff0c;因为无论如何都不可能覆盖所有的面试问题&…

国考省考结构化面试:情景模拟题的答题思路,人际关系题的变种,就题答题,灵活多变,关键在自己多思考,说话要有艺术

国考省考结构化面试&#xff1a;情景模拟题的答题思路&#xff0c;人际关系题的变种&#xff0c;就题答题&#xff0c;灵活多变&#xff0c;关键在自己多思考&#xff0c;说话要有艺术 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带…

ansible常用模块总结

目录 一、 assert模块 二、 authorized_key模块 三、at模块 四、blockinfile模块 五、command模块 六、copy模块 七、 cron模块 八、 firewalld模块 九、 fail模块 十、 file模块 十一、 fetch模块 十二、filesystem模块 十三、 get_url模块 十四、group模块 十…

基于pytorch+transformers的车牌识别

目录 程序流程设计熟悉训练数据集CCPD2019数据集CCPD数据集标注信息单例再现 加载本地车牌数据集 程序流程设计 1&#xff0c;熟悉训练数据集&#xff1b; 2&#xff0c;加载本地车牌数据集&#xff1b; 3&#xff0c;定义网络模型&#xff1b; 4&#xff0c;输入数据集训练模…

关于复杂事件处理和事件驱动架构的争论

复杂事件处理&#xff08;Complex Event Processing&#xff0c;CEP&#xff09;系统和事件驱动架构&#xff08;Event Driven Architecture&#xff0c;EDA&#xff09;都被认为会在目前和未来的精致繁杂的系统设计中扮演重要角色。但是它们的角色是什么&#xff1f;会对业界产…