国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

JavaScript 發(fā)布-訂閱設(shè)計(jì)模式實(shí)現(xiàn) React EventBus(相當(dāng)于vue的$Bus)非父子之間通信

這篇具有很好參考價(jià)值的文章主要介紹了JavaScript 發(fā)布-訂閱設(shè)計(jì)模式實(shí)現(xiàn) React EventBus(相當(dāng)于vue的$Bus)非父子之間通信。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

提前聲明: 我沒(méi)有對(duì)傳入的參數(shù)進(jìn)行及時(shí)判斷而規(guī)避錯(cuò)誤,僅僅對(duì)核心方法進(jìn)行了實(shí)現(xiàn);

解決了react的非父子間的通信;

參考文檔:https://github1s.com/browserify/events/blob/main/events.js

? ? ? ? ? ? ? ? ?https://www.npmjs.com/package/events

? ? ? ? ? ? ? ? ?https://github.com/browserify/events

? ? ? ? ? ? ? ? ?

1.其中的一種實(shí)現(xiàn)的方式? ?

?

首先先新建一個(gè)文件eventBus.tsx

class EventBus {
  constructor() {
    this.events = this.events || new Map(); // 儲(chǔ)存事件/回調(diào)鍵值對(duì)
    this.maxListeners = this.maxListeners || 10; // 設(shè)立監(jiān)聽(tīng)上限
  }

  // 觸發(fā)名為type的事件
  emit(type, ...args) {
    let handler = null;
    handler = this.events.get(type);
    console.log('?? ~ file: eventBus.js:11 ~ EventBus ~ emit ~ handler:', handler, args);
    if (handler === undefined) {
      return false;
    }
    if (Array.isArray(handler)) {
      // 如果是一個(gè)數(shù)組說(shuō)明有多個(gè)監(jiān)聽(tīng)者,需要依次此觸發(fā)里面的函數(shù)
      // eslint-disable-next-line no-plusplus
      for (let i = 0; i < handler.length; i++) {
        if (args.length > 0) {
          handler[i].apply(this, args);
        } else {
          handler[i].call(this);
        }
      }
    } else {
      // 單個(gè)函數(shù)的情況我們直接觸發(fā)即可
      // eslint-disable-next-line no-lonely-if
      if (args.length > 0) {
        handler.apply(this, args);
      } else {
        handler.call(this);
      }
    }
    return true;
  }

  // 監(jiān)聽(tīng)名為type的事件
  on(type, fn) {
    const handler = this.events.get(type);
    if (!handler) {
      this.events.set(type, fn);
    } else if (handler && typeof handler === 'function') {
      // 如果handler是函數(shù)說(shuō)明只有一個(gè)監(jiān)聽(tīng)者
      this.events.set(type, [handler, fn]); // 多個(gè)監(jiān)聽(tīng)者我們需要用數(shù)組儲(chǔ)存
    } else {
      handler.push(fn); // 已經(jīng)有多個(gè)監(jiān)聽(tīng)者,那么直接往數(shù)組里push函數(shù)即可
    }
  }

  // eslint-disable-next-line consistent-return
  remove(type, fn) {
    const handler = this.events.get(type); // 獲取對(duì)應(yīng)事件名稱(chēng)的函數(shù)清單
    if (handler && typeof handler === 'function') {
      // 如果是函數(shù),說(shuō)明只被監(jiān)聽(tīng)了一次
      this.events.delete(type, fn);
    } else {
      if (handler === undefined) {
        return false;
      }
      let position = null;
      // 如果handler是數(shù)組,說(shuō)明被監(jiān)聽(tīng)多次要找到對(duì)應(yīng)的函數(shù)
      // eslint-disable-next-line no-plusplus
      for (let i = 0; i < handler.length; i++) {
        if (handler[i] === fn) {
          position = i;
        } else {
          position = -1;
        }
      }
      // 如果找到匹配的函數(shù),從數(shù)組中清除
      if (position !== -1) {
        // 找到數(shù)組對(duì)應(yīng)的位置,直接清除此回調(diào)
        handler.splice(position, 1);
        // 如果清除后只有一個(gè)函數(shù),那么取消數(shù)組,以函數(shù)形式保存
        if (handler.length === 1) {
          this.events.set(type, handler[0]);
        }
      } else {
        return this;
      }
    }
  }
}

const eventBus = new EventBus();
export default eventBus;


// 簡(jiǎn)單實(shí)現(xiàn)的發(fā)布訂閱模式 也是對(duì)的
// class EventEmitter {
//   constructor() {
//     this.eventBus = this.eventBus || {};
//   }

//   emit(type, params) {
//     this.eventBus.type.forEach(item => {
//       item(params);
//     });
//   }

//   on(type, fn) {
//     if (this.eventBus.type) {
//       this.eventBus.type.push(fn);
//     } else {
//       this.eventBus.type = [fn];
//     }
//   }

//   remove(type, fn) {
//     if (this.eventBus[type]) {
//       delete this.eventBus.type
//     }
//   }
// }

// const eventBus = new EventEmitter();
// export default eventBus;

然后再組件A使用=>接收

import React, { useState, useEffect, useCallback } from 'react';
// import eventBus from '@/utils/events';
import eventBus  from '@/utils/eventBus';

const TopBox = () => {
  const [num, setNum] = useState(0);

  const addNum = useCallback((message: any) => {
    setNum(message);
  }, []);

  useEffect(() => {
    eventBus.on('emit', addNum);
    return () => {
      if(eventBus) {
        eventBus.remove('emit', addNum);
      }
    };
  }, []);

  return (
    <div>
      <span>我也不知道是什么111: {num}</span>
    </div>
  );
};

export default TopBox;

然后再組件B使用=>觸發(fā)

import React, { useState } from 'react';
import { Button } from 'antd';
// import eventBus from '@/utils/events';
import eventBus from '@/utils/eventBus';

const TopBox = () => {
  const [num,setNum] = useState(0)

  const addNum = () => {
    const numNew = num + 1;
    setNum(numNew);
    eventBus.emit('emit', numNew)
  }

  return (
    <div>
      <Button onClick={() => {addNum()}}>按鈕</Button>
      <span>我也不知道是什么:{num}</span>
    </div>
  );
};

export default TopBox;

?

?

2.其中的另一種實(shí)現(xiàn)的方式

安裝這個(gè)events插件

yarn add events

新建一個(gè)文件evnets.ts

import { EventEmitter } from 'events';
export default new EventEmitter();

組件A使用

import React, { useState, useEffect, useCallback } from 'react';
import eventBus from '@/utils/events';
// import eventBus  from '@/utils/eventBus';

const TopBox = () => {
  const [num, setNum] = useState(0);

  const addNum = useCallback((message: any) => {
    setNum(message);
  }, []);

  useEffect(() => {
    eventBus.on('emit', addNum);
    return () => {
      if(eventBus) {
        // eventBus.remove('emit', addNum);
        eventBus.removeListener('emit', addNum);
      }
    };
  }, []);

  return (
    <div>
      <span>我也不知道是什么111: {num}</span>
    </div>
  );
};

export default TopBox;

組件B使用

import React, { useState } from 'react';
import { Button } from 'antd';
import eventBus from '@/utils/events';
// import eventBus from '@/utils/eventBus';

const TopBox = () => {
  const [num,setNum] = useState(0)

  const addNum = () => {
    const numNew = num + 1;
    setNum(numNew);
    eventBus.emit('emit', numNew)
  }

  return (
    <div>
      <Button onClick={() => {addNum()}}>按鈕</Button>
      <span>我也不知道是什么:{num}</span>
    </div>
  );
};

export default TopBox;

?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-417306.html

到了這里,關(guān)于JavaScript 發(fā)布-訂閱設(shè)計(jì)模式實(shí)現(xiàn) React EventBus(相當(dāng)于vue的$Bus)非父子之間通信的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • js設(shè)計(jì)模式——發(fā)布訂閱模式

    一、概述 發(fā)布訂閱模式是一種常用的設(shè)計(jì)模式,它定義了一種一對(duì)多的關(guān)系,讓多個(gè)訂閱者對(duì)象同時(shí)監(jiān)聽(tīng)某一個(gè)主題對(duì)象,當(dāng)主題對(duì)象發(fā)生變化時(shí),它會(huì)通知所有訂閱者對(duì)象,使它們能夠自動(dòng)更新 。 二、優(yōu)缺點(diǎn) 1. 優(yōu)點(diǎn): 實(shí)現(xiàn)了發(fā)布者和訂閱者之間的解耦,提高了代碼的可

    2024年02月06日
    瀏覽(88)
  • 設(shè)計(jì)模式之觀察者(發(fā)布訂閱)模式

    設(shè)計(jì)模式之觀察者(發(fā)布訂閱)模式

    觀察者模式定義了一種一對(duì)多的依賴關(guān)系,讓多個(gè)觀察者對(duì)象同事監(jiān)聽(tīng)某一個(gè)主題對(duì)象。這個(gè)主題對(duì)象在狀態(tài)發(fā)生變化時(shí),會(huì)通知所有觀察者對(duì)象,使它們能夠自動(dòng)更新自己 觀察者模式主要解決的問(wèn)題: 當(dāng)一個(gè)對(duì)象狀態(tài)發(fā)生改變后給其他的對(duì)象通知 觀察者的優(yōu)點(diǎn): 觀察者和

    2024年02月07日
    瀏覽(86)
  • 設(shè)計(jì)模式(四) —— 觀察者模式/發(fā)布訂閱模式,c和c++示例代碼

    往期地址: 設(shè)計(jì)模式(一)——簡(jiǎn)單工廠模式 設(shè)計(jì)模式(二)——策略模式 設(shè)計(jì)模式(三)——裝飾模式 本期主題: 使用c和c++代碼,講解觀察者模式、發(fā)布訂閱模式 發(fā)布-訂閱模式是一種行為設(shè)計(jì)模式,它允許多個(gè)對(duì)象通過(guò)事件的發(fā)布和訂閱來(lái)進(jìn)行通信; 在這種模式中,

    2023年04月17日
    瀏覽(93)
  • RabbitMQ學(xué)習(xí)——發(fā)布訂閱/fanout模式 & topic模式 & rabbitmq回調(diào)確認(rèn) & 延遲隊(duì)列(死信)設(shè)計(jì)

    RabbitMQ學(xué)習(xí)——發(fā)布訂閱/fanout模式 & topic模式 & rabbitmq回調(diào)確認(rèn) & 延遲隊(duì)列(死信)設(shè)計(jì)

    1.rabbitmq隊(duì)列方式的梳理,點(diǎn)對(duì)點(diǎn),一對(duì)多; 2.發(fā)布訂閱模式,交換機(jī)到消費(fèi)者,以郵箱和手機(jī)驗(yàn)證碼為例; 3.topic模式,根據(jù)規(guī)則決定發(fā)送給哪個(gè)隊(duì)列; 4.rabbitmq回調(diào)確認(rèn),setConfirmCallback和setReturnsCallback; 5.死信隊(duì)列,延遲隊(duì)列,創(chuàng)建方法,正?!佬?,設(shè)置延遲時(shí)間; 點(diǎn)對(duì)

    2024年02月13日
    瀏覽(92)
  • RabbitMQ基礎(chǔ)(2)——發(fā)布訂閱/fanout模式 & topic模式 & rabbitmq回調(diào)確認(rèn) & 延遲隊(duì)列(死信)設(shè)計(jì)

    RabbitMQ基礎(chǔ)(2)——發(fā)布訂閱/fanout模式 & topic模式 & rabbitmq回調(diào)確認(rèn) & 延遲隊(duì)列(死信)設(shè)計(jì)

    1.rabbitmq隊(duì)列方式的梳理,點(diǎn)對(duì)點(diǎn),一對(duì)多; 2.發(fā)布訂閱模式,交換機(jī)到消費(fèi)者,以郵箱和手機(jī)驗(yàn)證碼為例; 3.topic模式,根據(jù)規(guī)則決定發(fā)送給哪個(gè)隊(duì)列; 4.rabbitmq回調(diào)確認(rèn),setConfirmCallback和setReturnsCallback; 5.死信隊(duì)列,延遲隊(duì)列,創(chuàng)建方法,正?!佬?,設(shè)置延遲時(shí)間; 點(diǎn)對(duì)

    2024年02月10日
    瀏覽(98)
  • JavaScript 簡(jiǎn)單實(shí)現(xiàn)觀察者模式和發(fā)布-訂閱模式

    JavaScript 簡(jiǎn)單實(shí)現(xiàn)觀察者模式和發(fā)布-訂閱模式

    大家好,我是南木元元,熱衷分享有趣實(shí)用的文章。今天來(lái)聊聊設(shè)計(jì)模式中常用的觀察者模式和發(fā)布-訂閱模式。 觀察者模式定義對(duì)象間的一種一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都將得到通知。 如何理解這句話呢?來(lái)舉個(gè)生活中的例子

    2024年02月12日
    瀏覽(638)
  • 4.設(shè)計(jì)模式之后七種模式后11種模式命令訪問(wèn)者迭代器發(fā)布訂閱中介者忘備錄解釋器狀態(tài)策略職責(zé)鏈和空模式

    4.設(shè)計(jì)模式之后七種模式后11種模式命令訪問(wèn)者迭代器發(fā)布訂閱中介者忘備錄解釋器狀態(tài)策略職責(zé)鏈和空模式

    1.命令(command)模式 不知道命令接收者(對(duì)象)是誰(shuí),支持撤銷(xiāo) (接受者 間接調(diào)用執(zhí)行 的具體行為) 命令調(diào)用者和接收者解耦 //只要實(shí)現(xiàn)命令接口即可 (就是客戶端給個(gè)命令,然后命令類(lèi)傳給接收類(lèi)執(zhí)行) 優(yōu)點(diǎn)和缺點(diǎn) 容易撤銷(xiāo)操作 命令隊(duì)列可以多線程操作 增加過(guò)多的命令類(lèi) 空命令也

    2024年02月12日
    瀏覽(96)
  • 設(shè)計(jì)模式 -- 策略模式(傳統(tǒng)面向?qū)ο笈cJavaScript 的對(duì)比實(shí)現(xiàn))

    規(guī)則:根據(jù)員工的工資基數(shù)和年底績(jī)效情況計(jì)算年終獎(jiǎng) 初級(jí)實(shí)現(xiàn) 缺點(diǎn) 多重 if else 違反開(kāi)發(fā)-封閉原則,可維護(hù)性差 復(fù)用性差 使用組合函數(shù)重構(gòu)代碼 使用組合函數(shù)來(lái)重構(gòu)代碼,把各種算法封裝到一個(gè)個(gè)的小函數(shù)里面,這些小函數(shù)有著良好的命名,可以一目了然地知道它對(duì)應(yīng)著

    2024年02月11日
    瀏覽(99)
  • 【JavaScript】手撕前端面試題:寄生組合式繼承 | 發(fā)布訂閱模式 | 觀察者模式

    ?????個(gè)人簡(jiǎn)介:大三學(xué)生,一個(gè)不甘平庸的平凡人?? ??? NodeJS專(zhuān)欄:Node.js從入門(mén)到精通 ??? 博主的前端之路(源創(chuàng)征文一等獎(jiǎng)作品):前端之行,任重道遠(yuǎn)(來(lái)自大三學(xué)長(zhǎng)的萬(wàn)字自述) ??? TypeScript知識(shí)總結(jié):TypeScript從入門(mén)到精通(十萬(wàn)字超詳細(xì)知識(shí)點(diǎn)總結(jié)) ??

    2023年04月08日
    瀏覽(96)
  • 前端設(shè)計(jì)模式:工廠方法模式、單例模式、訂閱模式、中介者模式

    工廠方法模式是一種創(chuàng)建型設(shè)計(jì)模式,它提供了一種將對(duì)象的創(chuàng)建與使用分離的方式。在工廠方法模式中,我們定義一個(gè)工廠接口,該接口聲明了一個(gè)用于創(chuàng)建對(duì)象的方法。具體的對(duì)象創(chuàng)建則由實(shí)現(xiàn)該接口的具體工廠類(lèi)來(lái)完成。 工廠方法模式的核心思想是將對(duì)象的創(chuàng)建延遲到

    2024年02月12日
    瀏覽(91)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包