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 でフィールドの前または後に文字列を追加する方法

推薦する

FileZilla_Server:425 データ接続を開けない問題を解決する方法

FileZilla Serverをサーバーにインストールすると、425データ接続を開けない問題が発生...

ページネーションの例とベストプラクティス

<br />構造と階層により複雑さが軽減され、読みやすさが向上します。記事やサイトが整理...

MySQLパーティションテーブルは月別に分類されています

目次テーブルを作成するデータベース ファイルを表示します。入れるクエリ消去補足:Mysqlは月テーブ...

Centos7 での MySQL のインストールに関するチュートリアル

最近、自宅サーバーにクラウドディスクを導入する予定なので、一連の環境構築作業を始めました。MySQL...

MySQL の JSON 挿入の問題

MySQL 5.7.8 以降では、JSON テキストでデータを効率的に取得できるネイティブ JSON...

HTML と CSS を使用して絵文字付きのコメント ボックスを作成する方法のチュートリアル

絵文字付きの HTML コメント ボックス。絵文字は Json データを通じて読み込まれ、好みに応じ...

Win10 インストール Linux システム チュートリアル ダイアグラム

Windows システムに仮想マシンをインストールするには、 VMware Workstationソ...

MySQLのSeconds_Behind_Masterの詳細な説明

目次マスターの後ろの秒数オリジナルの実装最終マスタータイムスタンプマスターとのクロック差他の実行時間...

Vue でルーティング遷移効果を実装する 4 つの方法

Vue ルーター トランジションは、Vue プログラムにパーソナライズされたエフェクトをすばやく簡単...

Win10にMySQL8圧縮パッケージ版をインストールするチュートリアル

1 公式サイトからMySQL8をダウンロードしてインストールするMySQL8 ダウンロードアドレスこ...

Vue ElementUI フォームのフォーム検証

フォーム検証は、フロントエンド開発プロセスで最もよく使用される機能の 1 つです。私の個人的な仕事経...

JSはカード配布アニメーションを実現します

この記事の例では、カード配布アニメーションを実装するためのJSの具体的なコードを参考までに共有してい...

Vue プロジェクトを実行するときに `--fix` オプションで修正できる可能性のある警告のエラー問題を解決します。

問題: vue-cil3 は、`--fix` オプションで修正できる可能性のある警告とともに実行され...

MySQLで日付と時刻を照会する方法

序文:プロジェクト開発では、一部のビジネス テーブル フィールドで日付と時刻の型が使用されることが多...