Vue组件自定义事件、全局事件总线、消息订阅与发布(pubsub)、$nextTick

news2024/12/23 0:29:32

目录

  • 1. 组件自定义事件
  • 2. 全局事件总线(GlobalEventBus)
  • 3. 消息订阅与发布(pubsub)
  • 4. this.$nextTick

1. 组件自定义事件

  1. 一种组件间通信的方式,适用于子组件给父组件传递数据。在父组件中给子组件绑定自定义事件,事件的触发在子组件,事件的回调函数在父组件中
  2. 绑定自定义事件:
    1. 第一种方式,在父组件中:<School @myEvent.once="callBackFunc"/>(只能被触发一次)或<School v-on:myEvent="callBackFunc"/>

    2. 第二种方式,在父组件中:先用<School ref="school "/>给子组件注册引用信息,这样就能获取到Student的组件实例对象vc。然后再在父组件中通过生命周期函数mounted进行绑定自定义事件

		mounted() {
		    // this.$refs.student.$once(......)    // 只能被触发一次
		    // 直接在这里实现callBackFunc,如果是普通函数,则普通函数里面的this是Student组件实例对象vc
		    // 如果是箭头函数,箭头函数没有this,则向外找,箭头函数里面的this是父组件的实例对象
			this.$refs.student.$on('myEvent', this.callBackFunc)
		}
  1. 触发自定义事件:在子组件中:this.$emit('myEvent', 'param1', param2)

  2. 事件回调函数:在父组件中:callBackFunc(param1, param2) {…}

  3. 解绑自定义事件:在子组件中:this.$off('myEvent')(解绑一个)、this.$off(['myEvent'])(解绑多个)、this.$off()(解绑所有)

  4. 在父组件中给子组件上绑定原生DOM事件,使用<School @click.native="callBackFunc"/>

使用示例
App.vue:绑定student2App组件自定义事件,事件的回调函数是getStudentName

<template>
	<div>
		<h1>App组件接收Student组件的学生姓名是:{{studentName}}</h1>

		<!-- 父组件给子组件绑定一个自定义事件 -->
		<Student ref="student"/>
	</div>
</template>

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

	export default {
		name:'App',
		components:{Student},
		data() {
			return {
				studentName:''
			}
		},
		methods: {
            // 事件的回调函数
			getStudentName(name, ...params){
        console.log(params)
				this.studentName = name
			}
		},
		mounted() {
            // 绑定自定义事件
			this.$refs.student.$on('student2App',this.getStudentName)
		}
	}
</script>

Student.vue:通过两个函数分别进行student2App组件自定义事件的触发和解绑

<template>
	<div>
		<h2>学生姓名:{{name}}</h2>
		<button @click="sendStudentlName">点我把学生名给App</button>
		<button @click="unbind">点我解绑student2App事件</button>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data() {
			return {
				name:'张三'
			}
		},
		methods: {
			sendStudentlName(){
				// 触发Student组件实例的student2App事件
				this.$emit('student2App',this.name,'param1',666)
			},
			unbind(){
                // 解绑多个自定义事件
				this.$off(['student2App'])
			}
		}
	}
</script>

先【点击把学生名给App】的效果如下,再【点击解绑student2App事件】,最后【点击把学生名给App】控制台没有输出
组件自定义事件

可以通过浏览器的Vue插件,查看组件自定义事件的触发记录,如下所示:
自定义事件的触发记录

2. 全局事件总线(GlobalEventBus)

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

示例如下:
main.js:安装全局事件总线,$bus就是当前应用的vm

import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false

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

App.vue

<template>
	<div>
		<School/>
		<Student/>
	</div>
</template>

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

	export default {
		name:'App',
		components:{School,Student}
	}
</script>

School.vue:

  1. 使用事件总线之接收数据:School组件想接收数据,则在School组件中给$bus绑定组件自定义事件,事件的回调函数在School组件中
  2. 在beforeDestroy回调函数中,用$bus.$off去解绑当前组件所用到的事件
<template>
	<div>
		<h2>学校名称:{{name}}</h2>
	</div>
</template>

<script>
	export default {
		name:'School',
		data() {
			return {
				name:'第一中学'
			}
		},
		mounted() {
      // 给$bus绑定自定义事件
      // 事件回调函数是School组件的。因为事件回调函数里面的this是School实例对象
			this.$bus.$on('student2School',(studentName)=>{
        console.log(this)
				console.log('我是School组件,收到了学生的名字: ', studentName)
			})
		},
		beforeDestroy() {
      // 销毁School组件前,解绑和该组件有关的组件自定义事件
			this.$bus.$off('student2School')
		}
	}
</script>

Student.vue:使用事件总线之提供数据。通过$bus.$emit触发指定的组件自定义事件并传递数据

<template>
	<div>
		<h2>学生姓名:{{name}}</h2>
		<button @click="sendStudentName">把学生名传递给School组件</button>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data() {
			return {
				name:'张三'
			}
		},
		methods: {
			sendStudentName(){
        // 触发$bus的组件自定义事件,同时传递值
				this.$bus.$emit('student2School',this.name)
			}
		}
	}
</script>

点击按钮,控制台输出如下:
全局事件总线

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

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

消息订阅与发布是一种思想,需要借助其它第三方库,这里选择pubsub-js,使用命令cnpm install pubsub-js进行项目包安装。因为浏览器的Vue插件不支持第三方的pubsub-js,所有在Vue的Timeline的Component-events看不到事件记录

School.vue:

  1. 接收数据:School组件想接收数据,则在School组件中订阅topic,订阅的回调函数在School组件中
  2. 取消订阅:最好在beforeDestroy钩子中,用PubSub.unsubscribe(subId)去取消订阅的topic
<template>
	<div>
		<h2>学校名称:{{name}}</h2>
	</div>
</template>

<script>
	import pubsub from 'pubsub-js'
	export default {
		name:'School',
		data() {
			return {
				name:'第一中学'
			}
		},
		mounted() {
			this.subId = pubsub.subscribe('student2SchoolTopic',(topicName, name)=>{
				console.log(this)
				console.log('收到Student发送的消息,学生名字是: ',name)
			})
		},
		beforeDestroy() {
			pubsub.unsubscribe(this.pubId)
		}
	}
</script>

Student.vue:提供数据:使用pubsub.publish('topicName',数据)

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

<script>
	import pubsub from 'pubsub-js'
	export default {
		name:'Student',
		data() {
			return {
				name:'张三'
			}
		},
		methods: {
			sendStudentName(){
				pubsub.publish('student2SchoolTopic',this.name)
			}
		}
	}
</script>

点击按钮,控制台输出如下:
消息订阅与发布

4. this.$nextTick

  • 作用:在下一次DOM更新结束后执行其指定的回调函数
  • 什么时候用:当改变数据后,要基于更新后的新DOM进行某些操作时,可以在nextTick所指定的回调函数中实现

App.vue:直接使用this.$refs.inputData.focus()是获取不到焦点的,因为此时input输入框还是隐藏的,等editInput函数执行完才会去重新加载新的DOM。所以使用this.$nextTick等DOM加载完毕后,再去调用this.$refs.inputData.focus()获取焦点

<template>
	<div>
    <span v-show="!isEdit">{{data}}</span>
    <input type="text" v-model="data" v-show="isEdit" @blur="handelBlur" ref="inputData">
    <button @click="editInput">点我编辑文字</button>
	</div>
</template>

<script>


	export default {
		name:'App',
    data() {
      return {
        data:'学习',
        isEdit:false
      }
    },
    methods:{
      editInput() {
        this.isEdit=true
        
        this.$nextTick(function() {
          this.$refs.inputData.focus()
        })
      },
      handelBlur() {
        this.isEdit=false
      }
    }
	}


</script>

点击按钮,input输入框就能自动获取焦点
nextTick

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

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

相关文章

渗透测试学习资源

burp学院 https://portswigger.net/burp/documentation/desktop/getting-started https://portswigger.net/web-security/ hacker101学院 https://www.hacker101.com/ https://github.com/bugcrowd/bugcrowd_university 如何白嫖自学网络安全技术&#xff0c;最稳最推荐的网…

Python | Leetcode Python题解之第394题字符串解码

题目&#xff1a; 题解&#xff1a; class Solution:def decodeString(self, s: str) -> str:stk []for ss in s:# 不是"]"&#xff0c;照单全收&#xff0c;进栈if ss!"]":stk.append(ss)else:# 遇到"]",把"[]"裹起来的单词取出…

CISAW常见3大认证方向介绍

对于网络安全领域的从业者来说&#xff0c;CISAW这一名称定不会陌生。 事实上&#xff0c;CISAW认证覆盖了三大专业方向&#xff0c;它们分别是安全集成、安全运维以及风险管理。 本文旨在介绍这三个方向的认证要求、目标人群和考试形式。 来找出最适合你的方向吧&#xff01…

重置vCenter Server的root密码

文章目录 重置vCenter Server的root密码一、vCenter Server 6.7之前的版本步骤&#xff1a; 二、vCenter Server 7.0及之后版本步骤&#xff1a; 注意事项 重置vCenter Server的root密码 在虚拟化环境中&#xff0c;VMware vCenter Server扮演着核心管理角色的重任。然而&…

如何在C#应用程序中使用 SQL Server LocalDB 数据库

0. 前言 SQL Server LocalDB 是 Microsoft 提供的一种轻量级 SQL Server 实例&#xff0c;专为开发和测试场景设计。它易于安装和配置&#xff0c;非常适合在本地计算机上进行开发工作。本文将介绍如何在 C# 应用程序中使用 SQL Server LocalDB&#xff0c;包括安装、配置和连接…

基于SpringBoot+Vue技术的宇宙动漫网站

基于SpringBootVue技术的宇宙动漫网站&#xff08;源码L文ppt&#xff09;4-022 系统设计 4.1 总体功能设计 一般个人用户和管理者都需要登录才能进入宇宙动漫网站&#xff0c;使用者登录时会在后台判断使用的权限类型&#xff0c;包括一般使用者和管理者,一般使用者只能…

Spark-ShuffleManager

一、上下文 《Spark-Task启动流程》中我们讲到了ShuffleMapTask中会对这个Stage的结果进行磁盘的写入&#xff0c;并且从SparkEnv中得到了ShuffleManager&#xff0c;且调用了它的getWriter方法并在这个Stage的入口处&#xff08;也就是RDD的迭代器数据源处&#xff09;调用了…

万界星空科技云MES系统:提升生产效率与质量

万界星空科技云MES系统是一款基于云计算技术的智能制造执行系统&#xff0c;它集成了生产计划、生产管理、质量管理、设备管理、仓储管理等多个核心功能模块&#xff0c;旨在为企业提供高效、灵活、安全的生产管理解决方案。以下是对万界星空科技云MES系统功能和应用范围的详细…

地理围栏,打造智能生活新边界

随着智能手机和其他移动设备的普及&#xff0c;用户对基于位置获取个性化服务的需求大幅增加&#xff0c;例如用户进入商圈范围并停留操作一段时间后&#xff0c;智能触发向用户推送该商圈吃、喝、玩、乐的优惠活动消息&#xff1b;又如当用户到达非常驻地的机场时触发围栏&…

2024-MongoDB中国用户大会

周五下午7个小时高铁从深圳赶到上海&#xff0c;周六一天大会&#xff0c;周天飞回深圳。特种兵行动参加“2024-MongoDB中国用户大会”。&#xff0c;缓了两天终于把素材整理出来了。 这也是首次参加MongoDB相关专题会议&#xff0c;MongoDB出现在我接触的大多数项目中&#xf…

什么是法定计量校准?法定计量工作中常会有哪些问题?

什么是法定计量校准&#xff1f; 法制计量校准是以掌握计量和计量的基本内容&#xff0c;依法规划、监督、管理计量为基础&#xff0c;通过政府、企业、个人等多种参与方式和对计量违法行为的监督、处罚。 法制计量校准的目的是为了提高计量工作水平&#xff0c;促进国民经济、…

Type-C接口 未来发展趋势

随着科技的进步&#xff0c;Type-C接口已经逐渐代替了传统的USB接口&#xff0c;Type-C接口的普及将会给我们生活带来很多的便利。 Typez-C接口主要包括正反可插&#xff0c;传输速率高&#xff0c;支持快充协议&#xff0c;安全性高&#xff0c;体积小巧&#xff0c;支持高速…

集团企业主数据管理项目实施步骤及要点

为打破数据孤岛&#xff0c;提升数据治理水平&#xff0c;某省级投资集团率先构建了主数据平台&#xff0c;并成功实现了财务系统、合同系统、人力资源系统及OA门户系统等多系统的无缝对接。通过主数据平台提供的标准化接口&#xff0c;这些关键业务系统能够高效获取所需的主数…

车辆违停智能监测摄像头

车辆违停是城市交通管理中常见的问题&#xff0c;给道路交通秩序和行车安全带来了一定的影响。为了有效监测和处置车辆违停行为&#xff0c;智能监测摄像头被广泛应用于城市道路和停车场等场所。这种摄像头结合了图像识别技术和人工智能算法&#xff0c;能够实时监测并识别违停…

3600关成语填字APP游戏ACCESS\EXCEL数据库

成语类的APP游戏在最近一两年内非常的火爆&#xff0c;其主要原因是几乎所有中国人都能够冲个几十上百关&#xff0c;学习和趣味共享。看图猜成语类的数据之前已经弄到过很多&#xff0c;今天这份成语填字的倒是头一份。 该数据做成的APP效果如下&#xff1a; 数据以\符号分隔…

QGIS编译好后 启动报错qgis.app_app.dll not find lqgis.envfor correct environment paths

报错&#xff1a;qgis.app_app.dll not find lqgis.envfor correct environment paths 一&#xff0c;把 qgis.exe 修改成qgis-bin.exe 二&#xff0c;拷贝osggeo4w下面的qgis-bin.env 文件到当前执行目录

24最新『ComfyUI』入门到入坟全套教程!!看到就是赚到!赶紧收藏!

前言 本文简介 Stable Diffusion WebUI 应该是大多数人第一次接触 SD 绘画的工具&#xff0c;这款工具简单易上手&#xff0c;但操作流程相对固定。如果你想拥有更自由的工作流&#xff0c;可以试试 ComfyUI。而且很多新的模型和功能在刚出现时 ComfyUI 的支持度都比较高&…

IDEA 更新后打开Java项目无法Run

问题 IDEA新建了Java项目&#xff0c;然后更新IDEA之后&#xff0c;没有勾选任何删除配置&#xff0c;但是在新版本打开项目时无法使用Run。 分析 首先这不是Edit Configurations能解决的问题&#xff0c;根因也不是。 打开Project Structure发现除了Name以外的配置都是不可用…

【Python入门】教你安装2024最新的Python,最新版全面教程!!!

2024安装Python的详细教程 一、准备工作 确定Python版本&#xff1a; 访问Python官网&#xff08;Welcome to Python.org&#xff09;&#xff0c;查看最新的稳定版本。在撰写本文时&#xff08;2024年9月&#xff09;&#xff0c;Python 3.x 是当前的主要版本&#xff0c;其…

linux 硬件 arm架构 汇编语言

1.cortex 1. Cortex-A 低功耗 消费类 ARM Cortex-A 系列处理器是一种广泛应用于 移动设备、嵌入式系统和物联网的高效能处理器&#xff0c;因其低功耗和高性能的特点而受到青睐。 2. Cortex-R 实时性 Cortex-R处理器针对高性能实时应用&#xff0c;例如硬盘控制器&#xff08;或…