1. 事業背景マスク レイヤーを使用してユーザーの異常な操作を遮断する方法は、フロントエンドでよく使用される方法です。ただし、一部のプロジェクトではマスク レイヤーが均一に管理されていないため、次のような問題が発生します。 2. 問題分析上記のような背景から、実際のプロジェクトでは管理用に共通のマスク レイヤー コンポーネントを追加することが合理的です。分析後、次の問題を解決する必要があります。 コンポーネント設計1.マスクレイヤーが表示されて閉じるときこの問題はさまざまなビジネスニーズに応じて決定されますが、著者は、ほとんどのマスクの表示と閉じ方は主にインターフェイスの要求と戻りに依存すると考えています。インターフェイスが要求保留状態にある場合、マスクレイヤーが表示され、すべてのインターフェイスが戻るとマスクが閉じられます。この記事では主に、インターフェース要求のマスキングの問題を解決します。ts で記述されており、すべての詳細が記載されているわけではありません。 2. マスク部品の設計Mask コンポーネントは、クラス内の詳細を保護するクラスです。 クラスマスク{ // マスクレイヤーを表示する 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つがあります。 インスタンス.インターセプター.リクエスト.使用((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. 結論この記事では、統合マスクレイヤーの背景、問題点、設計ソリューションについて紹介します。ただし、すべての詳細が記載されているわけではなく、実際のビジネスに基づいて選択する必要があります。しかし、全体的な計画は次のように記載されています。 Vue プロジェクトにインターフェース監視マスクを追加する方法については、これで終わりです。Vue インターフェース監視マスクに関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: CentOS のファイルと権限の基本操作チュートリアル
>>: MySQL の concat 関数についての簡単な説明。MySQL でフィールドの前または後に文字列を追加する方法
今日は、サイトの設定やウェブサイトのアップロードなど、FlashFXP の最も基本的な機能を紹介しま...
ウェブ上で証明書とキーをコピーするscp -rp -P52113 /application/ngin...
1. はじめにレスポンシブ Web デザインにより、Web サイトは複数のデバイスと複数の画面に同時...
目次SQLを理解するSELECTを理解するエイリアス定数をクエリし、固定定数列を追加します。重複行を...
まとめインタビュー中、MySQL インデックスの問題について議論しているときに、B+ ツリー、B ツ...
RULES を使用すると、テーブルの内部境界のスタイルを制御できます。基本的な構文<TABLE...
目次序文Ajax シリアルおよびパラレルAjaxの同時リクエスト制御のための2つのソリューションPr...
1 Dockerサービスを開始するまず、docker サービスを開始する方法を知っておく必要がありま...
目次1. 閉鎖の概念追加の知識ポイント: 2. 閉鎖の役割: 3. 閉鎖例3.1 liをクリックする...
目次メイントピック1. UbuntuにDockerをインストールする2. DockerにROS2-F...
1. yumソースを更新するCentOS7 のデフォルトの yum リポジトリの PostgreSQ...
[解決策1: パディングの実装]原理:要素の padding の値がパーセンテージの場合、このパーセ...
1. テーブルとパーティションを分割する必要があるのはなぜですか?日常の開発では、大きなテーブルに遭...
データベースはさておき、人生における方言とは何でしょうか?方言とは、ある場所特有の言語です。他の場所...
目次1.Json文字列1.1Json構文1.2 例2. クッキー2.1 使い方は? 3. ローカルス...