面接官:React/VueがEvent Busでコンポーネント通信できる以上、実現できますか.
6147 ワード
前言
本文のタイトルのテーマは他の問題から延びてきて、面接の中で面接官の常用のやり方、1つの問題をつかんでずっと深く掘り下げて、この問題が発生する前にきっとこの問題です.
React/Vueの異なるコンポーネント間でどのように通信していますか?
Vue親子コンポーネント用Props通信 非親子コンポーネント用Event Bus通信 プロジェクトが複雑であれば、Vuexなどのグローバル状態管理ライブラリ通信 が必要となる場合がある. React 親子コンポーネント、親->子直接Props、子->親callbackコールバック 非親子コンポーネント、パブリッシュ購読モードのEventモジュール プロジェクトが複雑であればRedux、Mobx等のグローバル状態管理ライブラリ を用いる.用新しいContext Api 私たちは大体以上の答えを持っています.次に、
私たちはNodeのEvent APIに倣って簡単なEventライブラリを実現し、彼はサブスクリプションモードを発表する典型的な応用である.
事前声明:我々は伝達されたパラメータをタイムリーに判断して誤りを回避せず、核心方法だけを実現した.
1.基本構造
1.1 classの初期化
ES 6の
イベントを格納構造として
1.2傍受とトリガ
トリガリスニング関数は
もちろんNodeがES 6+を全面的に抱擁した後、対応する
我々はイベントをトリガする
基本的なトリガ/リスニングを実現したようですが、複数のリスニング者がいたら?
はい、最初のトリガしかありませんので、改造する必要があります.
2.アップグレード改造
2.1リスニング/トリガのアップグレード
我々の
はい、これからは複数の傍受者の関数を楽しくトリガーすることができます.
2.2リスニングの削除
本文のタイトルのテーマは他の問題から延びてきて、面接の中で面接官の常用のやり方、1つの問題をつかんでずっと深く掘り下げて、この問題が発生する前にきっとこの問題です.
React/Vueの異なるコンポーネント間でどのように通信していますか?
Vue
$dispatch
(廃止済み)と$broadcast
(廃止済み)Event(Bus)
をどのように実現するかを聞く可能性があります.これは重要すぎるので、ほとんどのモジュール通信はアンドロイド開発中のEvent Bus
、Nodeを含む類似のモードに基づいています.jsにおけるEvent
モジュール(NodeにおけるほとんどのモジュールはEventに依存する、http、stream、buffer、fs
等を含む)私たちはNodeのEvent APIに倣って簡単なEventライブラリを実現し、彼はサブスクリプションモードを発表する典型的な応用である.
事前声明:我々は伝達されたパラメータをタイムリーに判断して誤りを回避せず、核心方法だけを実現した.
1.基本構造
1.1 classの初期化
ES 6の
class
キーワードを用いるEvent
を初期化し、Event
のイベントリストとリスナー上限を含む.イベントを格納構造として
Map
を選んだが、キー値ペアとしての格納方式Map
が一般のオブジェクトよりも適切であるため、操作もより簡潔であり、まずMapの基本的な使い方と特徴を見ることができる.class EventEmeitter {
constructor() {
this._events = this._events || new Map(); // /
this._maxListeners = this._maxListeners || 10; //
}
}
1.2傍受とトリガ
トリガリスニング関数は
apply
とcall
の2つの方法を用いることができ、少数のパラメータの場合call
の性能がよりよく、複数のパラメータの場合apply
の性能がよりよく、その年ノードのEventモジュールは3つのパラメータの下でcall
を用いなければapply
を用いる.もちろんNodeがES 6+を全面的に抱擁した後、対応する
call/apply
操作のReflect
の新しいキーワードが書き換えられたが、私たちはそんなに複雑に書きたくないので、簡略化版を作った. // type
EventEmeitter.prototype.emit = function(type, ...args){
let handler; // this._events
handler = this._events.get(type);
if (args.length > 0) {
handler.apply(this, args);
}else{
handler.call(this);
}
return true;
};
// type
EventEmeitter.prototype.addListener = function(type, fn) {
// type fn this._events
if (!this._events.get(type)) {
this._events.set(type, fn);
}
};
我々はイベントをトリガする
emit
方法とイベントを傍受するaddListener
方法を実現し、これにより簡単な実践を行うことができる.// const emitter = new EventEmeitter();
// arson
emitter.addListener('arson', man => {
console.log(`expel ${man}`);
});
// arson ,
emitter.emit('arson', 'low-end'); // expel low-end
基本的なトリガ/リスニングを実現したようですが、複数のリスニング者がいたら?
//
emitter.addListener('arson', man => {
console.log(`expel ${man}`);
});
emitter.addListener('arson', man => {
console.log(`save ${man}`);
});
emitter.emit('arson', 'low-end'); // expel low-end
はい、最初のトリガしかありませんので、改造する必要があります.
2.アップグレード改造
2.1リスニング/トリガのアップグレード
我々の
addListener
の実現方法はまだ健全ではなく、最初のリスナーをバインドした後、後続のリスナーをバインドすることができないため、後続のリスナーと最初のリスナー関数を1つの配列に配置する必要がある.// type
EventEmeitter.prototype.emit = function(type, ...args) {
let handler;
handler = this._events.get(type);
if (Array.isArray(handler)) {
// ,
for (let i = 0; i 0) {
handler[i].apply(this, args);
} else {
handler[i].call(this);
}
}
} else {
//
if (args.length > 0) {
handler.apply(this, args);
} else {
handler.call(this);
}
}
return true;
};
// type
EventEmeitter.prototype.addListener = function(type, fn) {
const handler = this._events.get(type);
//
if (!handler) {
this._events.set(type, fn);
} else if (handler && typeof handler === 'function') {
// handler
this._events.set(type, [handler, fn]);
//
} else {
handler.push(fn);
// , push
}
};
はい、これからは複数の傍受者の関数を楽しくトリガーすることができます.
//
emitter.addListener('arson', man => {
console.log(`expel ${man}`);
});
emitter.addListener('arson', man => {
console.log(`save ${man}`);
});
emitter.addListener('arson', man => {
console.log(`kill ${man}`);
});
//
emitter.emit('arson', 'low-end'); //expel low-end //save low-end //kill low-end
2.2リスニングの削除
removeListener
関数で傍受関数を除去しますが、匿名関数は削除できません.EventEmeitter.prototype.removeListener = function(type, fn) {
const handler = this._events.get(type); //
// ,
if (handler && typeof handler === 'function') {
this._events.delete(type, fn);
}else{
let postion; // handler ,
for (let i = 0; i
3.
Event
, , Event
, .
: , .
: removeAllListeners
, newListener
, , .
, Event , - , , Event.
Event , 300 , , , Event .
: 96
:https://juejin.im/post/5ac2fb886fb9a028b86e328c