Vue2-Vue3组件间通信-EventBus方式-函数封装

Vue3中采用EventBus方式进行组件间通信与Vue2有一定区别

1.创建EventBus

在Vue2中,我们可以在main.js中创建一个全局的EventBus,代码如下:

// EventBus.js
import Vue from 'vue'
const EventBus = new Vue()
export default EventBus

// main.js
import EventBus from './EventBus'
Vue.prototype.$bus = EventBus

在Vue3中,我们需要使用createApp来创建Vue实例,并使用provide和inject来创建全局的EventBus,代码如下:

// EventBus.js
import { createApp } from 'vue'
const app = createApp({})
const EventBus = app.provide('EventBus', new app())
export default EventBus

// main.js
import EventBus from './EventBus'
createApp(App).use(EventBus).mount('#app')


-----------------
// 在 main.js 或入口文件中
import { createApp, provide } from 'vue';
import App from './App.vue';

const app = createApp(App);
const eventBus = createApp({});

// 将 eventBus 实例作为提供者提供给子组件
app.provide('eventBus', eventBus);

app.mount('#app');

2.使用EventBus进行通信

在Vue2中,我们可以通过$emit和$on方法来进行通信,代码如下:

// 发送通信
this.$emit('event', data)

// 接收通信
this.$on('event', (data) => {
  console.log(data)
})

// 销毁
this.$off('event')

在Vue3中,我们可以通过$emit和$on方法来进行通信,但是需要在组件中使用AppContext来获取EventBus,代码如下:

// 发送通信
const app = getCurrentInstance().appContext.app
app.config.globalProperties.$EventBus.emit('event', data)

// 接收通信
const app = getCurrentInstance().appContext.app
app.config.globalProperties.$EventBus.on('event', (data) => {
  console.log(data)
})

//  销毁
const app = getCurrentInstance().appContext.app
app.config.globalProperties.$EventBus.off('event')


-------------------
import { inject } from 'vue';

export default {
  // ...
  created() {
    const eventBus = inject('eventBus');
    // 使用 eventBus 进行事件的发布和订阅
  },
  // ...
}

总的来说,Vue3与Vue2在EventBus方式上的区别不大,只是在创建全局EventBus的方式上有所不同,但是使用起来差异较大,需要根据实际情况进行选择。


封装EventBus.js

类方式 

class Event {
  constructor() {
    this.queue = {};
    this.onceQueue = {};
  }

  $on(name, callback) {
    this.queue[name] = this.queue[name] || [];
    this.queue[name].push(callback);
  }

  $once(name, callback) {
    this.onceQueue[name] = this.onceQueue[name] || [];
    this.onceQueue[name].push(callback);
  }

  $off(name, callback) {
    if (callback) {
      if (this.queue[name]) {
        for (var i = 0; i < this.queue[name].length; i++) {
          if (this.queue[name][i] === callback) {
            this.queue[name].splice(i, 1);
            break;
          }
        }
      }
    } else {
      delete this.queue[name];
    }
  }

  $emit(name, data) {
    if (this.queue[name]) {
      this.queue[name].forEach(function (callback) {
        callback(data);
      });
    }
    if (this.onceQueue[name]) {
      this.onceQueue[name].forEach(function (callback) {
        callback(data);
      });
      delete this.onceQueue[name];
    }
  }
}

export default new Event();



使用 

import Bus from '@/utils/EventBus';
Bus.$on('test', (data) => {})
Bus.$emit('close')
beforeUnmount() {
    Bus.$off('test', fun)
}

构造函数方式

function E() { }

// 函数E的原型对象
E.prototype = {
    // on方法:接受订阅名,订阅函数,上下文对象
    on: function (name, callback, context) {
        // 初始化e仓库
        var e = this.e || (this.e = {})
            // 收集订阅函数
            // 包装为对象,收集订阅函数与上下文对象
            ; (e[name] || (e[name] = [])).push({
                fn: callback,
                context
            })
        // 返回实例对象
        return this
    },
    // once函数:接收订阅名,订阅函数,上下文对象
    // 与on的区别是:once函数收集只执行一遍的订阅函数
    once: function (name, callback, context) {
        let self = this
        // 包装对象,用于自定义执行逻辑(删除操作)
        function listener() {
            self.off(name, listener)
            callback.apply(context, arguments)
        }
        // 保存原始函数
        listener._ = callback
        // 使用on收集自定义后的函数
        // 执行on方法会返回this,所以once函数内不需要返回this
        return this.on(name, listener, context)
    },
    // emit方法用于触发订阅函数:接收订阅名称
    emit: function (name) {
        // 收集参数
        let args = [].slice.call(arguments, 1)
        // 收集订阅函数数组
        let events = ((this.e || (this.e = {}))[name] || []).slice()

        let i = 0
        let len = events.length
        // 循环执行订阅函数
        for (; i < len; i++) {
            // 使用apply调用函数并绑定this
            events[i].fn.apply(events[i].context, args)
        }
        // 返回this实例
        return this
    },
    // off用于删除订阅函数:接收订阅名和订阅函数
    off: function (name, callback) {
        let e = this.e || (this.e = {})
        // 获取订阅名称对应的数组
        let events = e[name]
        let liveEvents = []
        // 处理函数数组&传入的订阅函数是否都存在?
        if (events && callback) {
            // 循环遍历,过滤操作
            for (let i = 0, len = events.length; i < len; i++) {
                // 判断数组中的订阅函数是否与传入的订阅函数相等?
                // 使用once创建的函数取_属性中的原始函数进行对比
                if (events[i].fn !== callback && events[i].fn._ !== callback) {
                    liveEvents.push(events[i])
                }
            }
        }
        // 重置订阅名结果数组
        (liveEvents.length) ? e[name] = liveEvents : delete e[name]
        // 返回实例this
        return this
    }
}

export default {
    $on: (...args) => E.prototype.on(...args),
    $once: (...args) => E.prototype.once(...args),
    $off: (...args) => E.prototype.off(...args),
    $emit: (...args) => E.prototype.emit(...args)
}

使用 

import Bus from "@/utils/EventBus2";
Bus.$on('test', (data) => {})
Bus.$emit('close')
beforeUnmount() {
    Bus.$off('test', fun)
}

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

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

相关文章

【网络】数据链路层

目录 一、以太网 二、以太网帧格式 三、 MTU 1、MTU概念 2、 MTU对IP协议的影响 3、MTU对UDP协议的影响 4、 MTU对于TCP协议的影响 四、MAC地址 五、 ARP协议 1、ARP协议的作用 2、ARP协议的工作流程 3、ARP数据报的格式 4、中间人 数据链路层解决的&#xff0c;是…

自动化测试的优缺点

围绕测试自动化有很多议论&#xff0c;组织正在进行大量投资以利用测试自动化的好处。测试自动化可以指使用软件工具自动执行测试、将实际结果与预期结果进行比较以及报告差异/错误的过程。实施测试自动化的主要原因之一是减少手动工作和相关风险&#xff0c;同时测试重复性任务…

实例详解如何选择滤波算法

在机器视觉中,图像滤波器无处不在。例如,它们用于减少图像噪声,改善对比度或检测边缘。本文将向您介绍MVTec HALCON中一些最常用的滤波器,它们是如何工作的以及可以用于什么。 mean_image:均值滤波器 首先,我们读取具有背景纹理的示例图像。我们的目标是在不改变实际信…

load、unload和pagehide、pageshow

一、load、unload和pagehide、pageshow的主要应用 1&#xff09;load 和 unload 事件监听web页面的进入和离开&#xff0c;一般用于页面的首次加载、刷新和关闭等操作的监听&#xff1b; 2&#xff09;pageshow 和 pagehide 事件多用于监听浏览器的前进和后退等。 二、pagesh…

【C++】——类和对象

目录 面向过程和面向对象的初步认识类的引入类的定义类的访问限定符及封装类的作用域类的实例化this指针类的6个默认成员函数构造函数析构函数 面向过程和面向对象的初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析求解问题的步骤&#xff0c;通过函数调用…

PHP使用PhpSpreadsheet实现导出Excel时带下拉框列表 (可支持三级联动)

因项目需要导出Excel表 需要支持下拉 且 还需要支持三级联动功能 目前应为PHPExcel 不在维护&#xff0c;固采用 PhpSpreadsheet 效果如图&#xff1a; 第一步&#xff1a;首先 使用composer 获取PhpSpreadsheet 我这里PHP 版本 7.4 命令如下&#xff1a; composer r…

【计算机视觉 | 目标检测 | 图像分割】arxiv 计算机视觉关于目标检测和图像分割的学术速递(7 月 31 日论文合集)

文章目录 一、检测相关(9篇)1.1 Semi-Supervised Object Detection in the Open World1.2 Multi-layer Aggregation as a key to feature-based OOD detection1.3 Non-invasive Diabetes Detection using Gabor Filter: A Comparative Analysis of Different Cameras1.4 Local …

ABAP 自定义搜索功能 demo1

ABAP 自定义搜索功能 demo1 效果&#xff1a; 双击选中行则为选中对应发票 实现 1定义 定义屏幕筛选参数 SELECTION-SCREEN BEGIN OF SCREEN 9020. SELECT-OPTIONS:s1_belnr FOR rbkp-belnr, s1_gjahr FOR rbkp-gjahr, s1_lifnr FOR rbkp-lifnr, s1_erfna FOR rbkp-erfnam, …

详解AMQP协议

目录 1.概述 1.1.简介 1.2.抽象模型 2.spring中的amqp 2.1.spring amqp 2.2.spring boot amqp 1.概述 1.1.简介 AMQP&#xff0c;Advanced Message Queuing Protocol&#xff0c;高级消息队列协议。 百度百科上的介绍&#xff1a; 一个提供统一消息服务的应用层标准高…

插入排序算法

插入排序 算法说明与代码实现&#xff1a; 以下是使用Go语言实现的插入排序算法示例代码&#xff1a; package mainimport "fmt"func insertionSort(arr []int) {n : len(arr)for i : 1; i < n; i {key : arr[i]j : i - 1for j > 0 && arr[j] > …

深入理解负载均衡原理及算法

1. 前言 在互联网早期,网络还不是很发达,上网用户少,流量相对较小,系统架构以单体架构为主。但如今在互联网发达的今天,流量请求动辄百亿、甚至上千亿,单台服务器或者实例已完全不能满足需求,这就有了集群。不论是为了实现高可用还是高性能,都需要用到多台机器来扩展服…

react中hooks分享

一. HOOKS是什么 在计算机程序设计中&#xff0c;钩子一词涵盖了一系列技术&#xff0c;这些技术用来通过拦截函数调用、消息或在软件组件之间传递的事件来改变或增加操作系统、应用程序或其他软件组件的行为。处理这些被截获的函数调用、事件或消息的代码称为“hook”。 在r…

【Python】PySpark 数据计算 ⑤ ( RDD#sortBy方法 - 排序 RDD 中的元素 )

文章目录 一、RDD#sortBy 方法1、RDD#sortBy 语法简介2、RDD#sortBy 传入的函数参数分析 二、代码示例 - RDD#sortBy 示例1、需求分析2、代码示例3、执行结果 一、RDD#sortBy 方法 1、RDD#sortBy 语法简介 RDD#sortBy 方法 用于 按照 指定的 键 对 RDD 中的元素进行排序 , 该方…

细讲一个 TCP 连接能发多少个 HTTP 请求(一)

一道经典的面试题是从 URL 在浏览器被被输入到页面展现的过程中发生了什么&#xff0c;大多数回答都是说请求响应之后 DOM 怎么被构建&#xff0c;被绘制出来。但是你有没有想过&#xff0c;收到的 HTML 如果包含几十个图片标签&#xff0c;这些图片是以什么方式、什么顺序、建…

Arthas GC日志-JVM(十八)

上篇文章说jvm的实际运行情况。 Jvm实际运行情况-JVM&#xff08;十七&#xff09; Arthas介绍 因为arthas完全是java代码写的&#xff0c;我们直接用命令启动&#xff1a; Java -jar arthas-boot.jar 启动成功后&#xff0c;选择我们项目的进程。 进入我们可用dashboard…

django实现部门表的增删改查界面

1、前期准备 部署好mysql数据库&#xff0c;创建好unicom数据库下载好bootstap的插件下载好jquery的插件下载好mysqlclient-1.4.6-cp36-cp36m-win_amd64.whl的安装包&#xff0c;根据python的版本下载 2、创建项目 在pycharm中创建项目 在pycharm的终端创建虚拟环境 py -m v…

【Docker】Docker安装Elasticsearch服务的正确方式

文章目录 1. 什么是Elasticsearch2. Docker安装Elasticsearch2.1 确定Elasticsearch的版本2.2. Docker安装Elasticsearch2.3. 给Elasticsearch安装中文分词器IKAnalyzer&#xff08;可选&#xff09; 点击跳转&#xff1a;Docker安装MySQL、Redis、RabbitMQ、Elasticsearch、Na…

Django使用uwsgi+nginx部署,admin没有样式解决办法

Django使用uwsginginx部署,admin没有样式解决办法 如果使用了虚拟环境则修改nginx.conf文件中的/static/路径为你虚拟环境的路径&#xff0c;没有使用虚拟环境则改为你python安装路径下的static server {listen 8008;server_name location; #改为自己的域名&#xff0c;没域名…

mybatisplus实现自动填充 时间

mybatisplus实现自动填充功能——自动填充时间 数据库表中的字段 创建时间 (createTime)更新时间 (updateTime) 每次 增删改查的时候&#xff0c;需要通过对Entity的字段&#xff08;createTime&#xff0c;updateTime&#xff09;进行set设置&#xff0c;但是&#xff0c;每…

途乐证券|俄罗斯宣布9月削减石油出口量

当地时间周四&#xff0c;美股兜售潮仍在持续&#xff0c;三大股指连续第二个交易日团体收跌。到收盘&#xff0c;道指跌落0.19%&#xff0c;标普500指数跌落0.25%&#xff0c;纳指跌幅为0.10%。 美国ISM7月非制造业PMI下滑 数据面上&#xff0c;美国供应办理协会ISM周四发布的…