Vue プロジェクトにインターフェース リスニング マスクを追加する方法

Vue プロジェクトにインターフェース リスニング マスクを追加する方法

1. 事業背景

マスク レイヤーを使用してユーザーの異常な操作を遮断する方法は、フロントエンドでよく使用される方法です。ただし、一部のプロジェクトではマスク レイヤーが均一に管理されていないため、次のような問題が発生します。
(1)すべてのビジネスコンポーネントはマスクレイヤーコンポーネントを導入する必要があります。つまり、各.vueビジネスコンポーネントはテンプレートにマスクコンポーネントを導入します。コンポーネントがプロジェクトの隅々まで存在し、管理に役立たず、コードが極めて冗長になっています。
(2)マスクコンポーネントは業務全体に散在しているため、マスクレイヤーを表示するかどうかを制御する変数も業務コンポーネント内に散在している。たとえば、maskShow を使用してマスク レイヤーを表示するかどうかを制御すると、より複雑なプロジェクトでは 200 を超える maskShow 変数が生成されます。
(3) maskShowが多すぎて、業務に統合されています。同時に、maskShow変数はインターフェースのコールバック関数に記述されることが多く、変数の変更を忘れて、マスクレイヤーを表示するかどうかの論理エラーが発生することがよくあります。
(4) プロジェクトはローカルでデバッグされることが多いが、実際にはオンラインで実行される。(3) の問題はローカルでは検証できないことが多い。これらの問題は、オンラインネットワーク環境が悪い場合によく発生するためです。例えば、ボタンを押した後、再度クリックするにはインターフェースが戻るまで待つ必要がありますが、ローカルの戻り速度の方が速いため、マスクレイヤーの追加を忘れても問題ありません。しかし、オンラインでネットワークに問題がある場合は、この問題が発生しやすく、一度発生すると原因の特定が難しく、作業効率に大きな影響を与えます。

2. 問題分析

上記のような背景から、実際のプロジェクトでは管理用に共通のマスク レイヤー コンポーネントを追加することが合理的です。分析後、次の問題を解決する必要があります。
(1)マスクレイヤーの表示と閉じのタイミング
(2)マスク部品の設計
(3)結合を生じさせずにコンポーネントをプロジェクトにエレガントに導入する方法。
(4)大規模な問題を起こさずに、既存のプロジェクトでオリジナルのmaskShowメソッドを段階的に置き換える方法。
(5)詳細

コンポーネント設計

1.マスクレイヤーが表示されて閉じるとき

この問題はさまざまなビジネスニーズに応じて決定されますが、著者は、ほとんどのマスクの表示と閉じ方は主にインターフェイスの要求と戻りに依存すると考えています。インターフェイスが要求保留状態にある場合、マスクレイヤーが表示され、すべてのインターフェイスが戻るとマスクが閉じられます。この記事では主に、インターフェース要求のマスキングの問題を解決します。ts で記述されており、すべての詳細が記載されているわけではありません。

2. マスク部品の設計

Mask コンポーネントは、クラス内の詳細を保護するクラスです。
(1)このクラスの主な機能は、マスクレイヤーの追加と削除、現在のリクエストインターフェースのURLの送信です。

クラスマスク{
 // マスクレイヤーを表示する appendMask(url: string): void{}

 // マスクレイヤーを削除します。removeMaskl(url: string): void{}
}

(2)マスクレイヤー関数を追加し、リクエストがあったときにその関数を呼び出し、現在のインターフェースURLを渡します。保留中のリクエストがあるかどうかを監視するために、関数内に監視オブジェクトが維持されます。このオブジェクトの値は、このインターフェースの保留状態の数です。マスク ビュー コンポーネントが Vue プロトタイプ チェーンにマウントされていると想定し、マウントされていない場合はコンポーネントの上に導入するだけです。

//リスニングオブジェクトのデータ型を定義するインターフェイス HTTPDictInterface {
 [インデックス: 文字列]: 数値;
}

追加マスク(url: 文字列): void{ 

 if (!this.monitorHTTPDict[url]) {
 this.monitorHTTPDict[url] = 0;
 }
 this.monitorHTTPDict[url] += 1;

 // 監視インターフェースがある場合はマスクレイヤーを表示します if(!this.mask && Object.keys(this.monitorHTTPDict).length){

 // ボディにマスク レイヤー スタイルを追加します。$Mask はマスク レイヤー スタイル コンポーネントです。const Constructor = Vue.extend(Vue.prototype.$Mask);
 this.mask = 新しいコンストラクタ().$mount();

 document.body.appendChild(this.mask.$el);
 }
}

(3)マスク層を削除する関数。この関数は各リクエストの終了後に呼び出されます。リクエスト監視オブジェクトが空であることがわかった場合、マスク層は削除されます。保留状態のインターフェースがない場合、接続キーを削除します。オブジェクトが空でマスク レイヤーがある場合は、マスク レイヤーを削除します。

マスクを削除します(url: 文字列): void{

 // 成功したら戻ります if (this.monitorHTTPDict[monitorUrl]) {
 this.monitorHTTPDict[モニターUrl] -= 1;
 (this.monitorHTTPDict[monitorUrl] <= 0)の場合{
 this.monitorHTTPDict[monitorUrl]を削除します。
 }
 }

 // hasMask は、ページにマスクレイヤータグ要素があるかどうかを検出するために使用されます if (this.mask && this.hasMask() && !Object.keys(this.monitorHTTPDict).length) {
 document.body.removeChild(this.mask.$el);
 this.mask = null;
 }

 this.timer = null;
}

3. 結合せずにこのコンポーネントをプロジェクトにエレガントに導入する方法。

このコンポーネントを使用するには、すべてのリクエストが開始される前に appendMask 関数を呼び出し、すべてのリクエストが完了した後に removeMask 関数を呼び出す必要があります。呼び出し方法は以下の2つがあります。
(1)axiosなどのコンポーネントのコールバックを使用して関数呼び出しを完了します。ただし、このアプローチでは、Mask コンポーネント コードはプロジェクトから独立せず、特定のインターフェイス フレームワークの API に依存します。

インスタンス.インターセプター.リクエスト.使用((config) => {

 // マスクレイヤーを追加します。mask.appendMask(config.url);

 設定を返します。
});

(2)init関数を追加し、コールバックをネイティブXMLHttpRequestオブジェクトに直接挿入します。ネイティブ XMLHttpRequest 関数を変更し、イベント 'loadstart' および 'loadend' にコールバックを挿入します。loadstart によって受信されるパラメーターには現在のリクエストの URL が含まれていないため、open 関数を書き換えて、open によって受信された URL を新しい xhr オブジェクトにマウントする必要があることに注意してください。この方法は注意して使用してください。ネイティブ API を変更することは非常に危険であり、多くのコーディング標準で禁止されているため、全員がネイティブ API を書き換えると、これらのフレームワークが同時に導入されたときに競合が発生し、予期しない結果が発生します。

//パラメータを渡すことでこのメソッドを使用するかどうかを決定します init(){
 if (this.autoMonitoring){
 this.initRequestMonitor();
 }
}

// 新しい xmlhttprequest 型インターフェース NewXhrInterface は XMLHttpRequest を拡張します{
 リクエストURL?: 文字列
}

// ネイティブインジェクション initRequestMonitor(): void{

 OldXHR を window.XMLHttpRequest にします。
 maskClass: マスク = this;

 // @ts-ignore、コーディング標準ではXMLHttpRequestの変更は許可されていません
 window.XMLHttpRequest = 関数 () {

 realXHR: NewXhrInterface = new OldXHR();
 oldOpen を実行します: Function = realXHR.open;

 realXHR.open = (...args: (文字列 | ブール値 | 未定義 | null)[]): void => {

 realXHR.requestUrl = (args[1] を文字列として);
 oldOpen.apply(realXHR、引数);

 };

 realXHR.addEventListener(`loadstart`, () => {

 const requestUrl: string = (realXHR.requestUrl を文字列として);

 定数 url: 文字列 = maskClass.cleanBaseUrl(requestUrl);

 // マスクを開く maskClass.appendMask(url);
 });

 realXHR.addEventListener(`loadend`, () => {

 const responseURL: string = (realXHR を XMLHttpRequest として).responseURL;
 定数 url: 文字列 = maskClass.cleanBaseUrl(responseURL);

 // マスクを削除します maskClass.removeMask(url);
 });

 realXHR を返します。
 };
}

(3)インジェクションの使用法、initを直接呼び出します。この方法では、プロジェクトを変更するすべてのリクエストがマスクを通過することになります。

新しいマスク().init()

4. 大規模な問題を引き起こすことなく、既存のプロジェクトで元の maskShow メソッドを段階的に置き換える方法。

プロジェクト全体で直接使用すると、関係する領域が非常に広くなり、広範囲にわたって問題が発生し、逆効果になります。したがって、スムーズな移行を実現するために、段階的な置き換えアプローチを採用する必要があります。主なアイデアは、ページとブラックリストを構成することによって、どのページにコンポーネントを導入するかを決定し、各チームメンバーが自分で変更できるようにすることです。結局のところ、ページの担当者は、現在のページビジネスを最もよく知っている人です。ブラックリストにするかホワイトリストにするかは、プロジェクトの具体的な業務内容によって決まります。

// キーは監視する必要があるルーティング ページ、値は配列、配列に入力されたインターフェースは監視する必要のないブラックリスト インターフェースです。const PAGE_ONE = `/home`;
const PAGE_TWO = `/login`;
定数 HTTO_ONE = `xxx`

エクスポートconst maskUrlList = {
 [ページ 1]: [HTTO_ONE],
 [ページ2]: [],
};

appendMask メソッドは、ブラックリストに登録されたページと未構成のページをフィルタリングします。 maskUrlList は制御対象オブジェクトです。最初にページルートをチェックし、次にブラックリストがあるかどうかをチェックします。

追加マスク(url: 文字列): void{

 // 現在のページのパスを取得し、ページ パスを取得し、ハッシュ モードと履歴モードを区別します。const monitorPath: string = this.getMonitorPath();

 // maskUrlList は設定項目です。まずページルートをチェックし、次にブラックリストがあるかどうかをチェックします。if (this.maskUrlList[monitorPath]
 && !this.maskUrlList[monitorPath].includes(url)) {
 if (this.monitorHTTPDict[url] === 未定義) {
 this.monitorHTTPDict[url] = 0;
 }
 this.monitorHTTPDict[モニターUrl] += 1;
 }

 // マスクレイヤーを追加if (!this.mask && this.hasMonitorUrl()) {
 const コンストラクター = Vue.extend(Vue.prototype.$Mask);
 this.mask = 新しいコンストラクタ().$mount();

 document.body.appendChild(this.mask.$el);
 }
}

5. 詳細

(1) マスクレイヤーはレンダリング後に閉じられ、実際のマスクレイヤーの削除ロジックはタイマーに配置されます。Vue の非同期レンダリングは promise を使用するため、レンダリング後に閉じられる場合は setTimeout に配置する必要があります。これにはイベント ループに関する知識が必要です。インターフェイスが戻ったときに、ページをレンダリングする必要がある場合、Promise が非同期に実行されます。Promise はマイクロタスクであり、setTimeout はマクロタスクです。メイン スレッドが実行されると、最初にマイクロタスクが実行され、次に非同期マクロタスク setTimeout が実行されます。

//マスクレイヤーをクリアif (!this.timer) {
 this.timer = window.setTimeout(() => {

 if (this.mask && this.hasMask() && !this.hasMonitorUrl()) {
 document.body.removeChild(this.mask.$el);
 this.mask = null;
 }

 this.timer = null;

 }, 0);
}

(2)インターフェースをフィルタリングする場合は「?」、ハッシュモードでは「#」。

// リクエストインターフェースのURLを取得する
getMonitorUrl(url: 文字列): 文字列{
 const urlIndex: number = url.indexOf(`?`);
 monitorUrl: 文字列 = url;
 urlIndex !== -1 の場合 {
 monitorUrl = url.substring(0, urlIndex);
 }
 monitorUrl を返します。
}
// 現在のルートパスを取得する
getMonitorPath(): 文字列{

 const path: string = this.mode === HASH_TYPE ? window.location.hash : window.location.pathname;

 monitorPath: 文字列 = パス;

 if (this.mode === HASH_TYPE) {
 monitorPath = monitorPath.substring(path.indexOf(`#`) + 1);
 }

 // スクリーンショットのパス、リクエストパラメータの削除 const hashIndex: number = monitorPath.indexOf(`?`);

 ハッシュインデックスが -1 の場合
 monitorPath = monitorPath.substring(0, ハッシュインデックス);
 }

 monitorPath を返します。
}

(3)インターフェースフィルタリングbaseUrl注意深く見れば、axios インターフェースを使用するときに、リクエスト時に差別化されたフィルタリングを実行するため、baseUrl を取り込むかどうかを決定できることがわかります。プロジェクトの初期段階で使用方法が明確に定義されていない場合、axios を使用するには 2 つの異なる方法があります。次に、baseUrl をフィルタリングする必要があります。

// ベースURLを削除
cleanBaseUrl(fullUrl: 文字列): 文字列 {

 const baseUrlLength: 数値 = this.baseUrl.length;
 fullUrl.substring(baseUrlLength) を返します。
 
}

(4)コンポーネントの初期化:パラメータを渡してオブジェクトをインスタンス化します。

新しいマスク({
 modeType、// ハッシュまたは履歴
 autoMonitoring, // ネイティブ XMLHttpRequest オブジェクトを更新するかどうか maskUrlList, // インポートされたページとインターフェースを構成する baseUrl, // 現在のプロジェクトのベース URL
 ...
}).init()

IV. 結論

この記事では、統合マスクレイヤーの背景、問題点、設計ソリューションについて紹介します。ただし、すべての詳細が記載されているわけではなく、実際のビジネスに基づいて選択する必要があります。しかし、全体的な計画は次のように記載されています。
(1)マスクレイヤーは、一部のインターフェースが保留中のときに表示され、すべてのインターフェースが復帰した後に自動的に閉じられる必要があります。ここでのインターフェースとは、監視する必要があるインターフェースを指します。(2) コンポーネントの最も重要な2つの機能は、マスクレイヤーを追加するappendMaskとマスクレイヤーを削除するremoveMaskです。
(3)マスクを完全に独立させ、サードパーティのライブラリ(axios)からのコールバックに依存したくない場合は、XMLHttpRequestを直接書き換えることもできますが、これは非常にリスクが高いためお勧めできません。
(4)コンポーネントの交換により、チームメンバーが独自のルーティングおよびリスニングインターフェースを構成する方法が統一されます。ここでのロジックは自分で決めることができます。監視するインターフェースが多数ある場合はブラックリストを使用でき、そうでない場合はホワイトリストを使用できます。
(5)レンダリング、リクエストパラメータ、ルーティングモードを最適化しました。

Vue プロジェクトにインターフェース監視マスクを追加する方法については、これで終わりです。Vue インターフェース監視マスクに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Vueはプロキシを使用してすべてのインターフェースステータスメソッドを監視します

<<:  CentOS のファイルと権限の基本操作チュートリアル

>>:  MySQL の concat 関数についての簡単な説明。MySQL でフィールドの前または後に文字列を追加する方法

推薦する

Nginx リバース プロキシを使い始める

目次概要リバースプロキシの役割Nginx リバース プロキシ イントラネット侵入 8081 ポートの...

Dockerイメージを完全にアンインストールする手順

1. docker ps -a 実行中のイメージプロセスを表示する [root@mylinux~]#...

HTML フォーム コンポーネントのサンプル コード

HTML フォームは、さまざまな種類のユーザー入力を収集するために使用されます。次のコードは、HTM...

Nginx 設定ファイルの詳細な説明と最適化の提案ガイド

目次1. 概要2. nginx.conf 1) 設定ファイルの場所2) ワーカープロセス3) イベン...

MySQLストアドプロシージャを変更する詳細な手順

序文実際の開発では、ビジネス要件が変更されることが多いため、ストアド プロシージャの特性を変更するこ...

CSS はモバイル デバイスで水平スクロール ナビゲーション バーを実装します (PC デバイスにも適用可能)

関数の起源最近、水平スクロール バーを必要とする H5 に取り組んでいました。いくつかのドキュメント...

Linux でユーザーをグループに追加する 4 つの方法の概要

序文Linux グループは、Linux でユーザー アカウントを管理するために使用される組織単位です...

Linux の操作とメンテナンスの基本的なスワップ パーティションと LVM 管理のチュートリアル

目次1. スワップパーティション SWAP 1.1 スワップファイルを作成する1.2 スワップパーテ...

LinuxカーネルとSVNバージョン間の競合の解決策

現象システムは Linux システムカーネルを正常にコンパイルできましたが、SVN をインストールし...

VMware で Centos7 ブリッジ ネットワークを構成する手順の詳細な説明

VMware仮想マシンでのCentos7ブリッジネットワーク構成の完全な手順は参考用です。具体的な内...

React Hooks に基づく小さな状態管理の詳細な説明

目次React Hooks に基づく状態共有の実装ユーザーエクスペリエンスこの記事では、主に Rea...

CentOs7 64 ビット MySQL 5.6.40 ソースコードのインストール プロセス

1. インストールプロセス中に問題が発生しないように、まず依存パッケージをインストールします。 [r...

Mapper SQL ステートメント フィールドとエンティティ クラス属性名の関係は何ですか?

背景: 1. データベースに通知テーブルがある あなたは見ることができますgmt_create、通知...

Vue のディスパッチとブロードキャストの自己実装の詳細説明 (ディスパッチとブロードキャスト)

解決すべき問題主にコンポーネント間のクロスレベル通信用なぜディスパッチとブロードキャストを自分で実装...

nginx を使用して同じドメイン名で複数の Vue プロジェクトをデプロイし、リバース プロキシを使用する方法

効果現在、プロジェクトは2つ(project1、project2)あり、nginxに付属するinde...