So fügen Sie eine Schnittstellen-Abhörmaske in ein Vue-Projekt ein

So fügen Sie eine Schnittstellen-Abhörmaske in ein Vue-Projekt ein

1. Geschäftshintergrund

Die Verwendung einer Maskenebene zum Abschirmen abnormaler Benutzervorgänge ist eine Methode, die häufig vom Front-End verwendet wird. In einigen Projekten wird die Maskenebene jedoch nicht einheitlich verwaltet, was zu folgenden Problemen führt:
(1) Alle Geschäftskomponenten müssen die Maskenschichtkomponente einführen, d. h. jede .vue-Geschäftskomponente führt die Maskenkomponente in der Vorlage ein. In jeder Ecke des Projekts sind Komponenten vorhanden, was der Verwaltung nicht förderlich ist und den Code äußerst redundant macht.
(2) Maskenkomponenten sind im gesamten Unternehmen verstreut. Daher sind die Variablen, die steuern, ob die Maskenebene angezeigt werden soll, auch in den Geschäftskomponenten verstreut. Wenn Sie beispielsweise „maskShow“ verwenden, um zu steuern, ob die Maskenebene angezeigt werden soll, werden in einem komplexeren Projekt mehr als 200 „maskShow“-Variablen generiert.
(3) Es gibt zu viele MaskShows und sie sind in das Geschäft integriert. Gleichzeitig werden die MaskShow-Variablen häufig in die Rückruffunktion der Schnittstelle geschrieben. Es kommt häufig vor, dass vergessen wird, die Variablen zu ändern, was zu logischen Fehlern führt, ob die Maskenebene angezeigt werden soll oder nicht.
(4) Projekte werden häufig lokal debuggt, laufen aber tatsächlich online. Probleme in (3) können häufig nicht lokal verifiziert werden. Denn diese Probleme treten häufig auf, wenn die Online-Netzwerkumgebung schlecht ist. Wenn Sie beispielsweise eine Taste drücken, müssen Sie warten, bis die Schnittstelle zurückkehrt, bevor Sie erneut darauf klicken können. Da die lokale Rückkehrgeschwindigkeit jedoch schneller ist, gibt es kein Problem, wenn Sie vergessen, eine Maskenebene hinzuzufügen. Wenn es jedoch Online-Netzwerkprobleme gibt, kann dieses Problem leicht auftreten. Und wenn es erst einmal auftritt, ist es schwer zu lokalisieren, was die Arbeitseffizienz stark beeinträchtigt.

2. Problemanalyse

Vor diesem Hintergrund ist es sinnvoll, in tatsächlichen Projekten eine gemeinsame Maskenebene-Komponente für die Verwaltung hinzuzufügen. Nach der Analyse müssen die folgenden Probleme gelöst werden:
(1) Der Zeitpunkt des Erscheinens und Schließens der Maskenebene.
(2) Entwurf der Maskenkomponente.
(3) Wie kann die Komponente elegant in das Projekt eingeführt werden, ohne dass eine Kopplung entsteht?
(4) So ersetzen Sie die ursprüngliche MaskShow-Methode in vorhandenen Projekten schrittweise, ohne große Probleme zu verursachen.
(5) Einzelheiten

Komponentendesign

1. Wenn die Maskenebene erscheint und schließt

Diese Frage wird entsprechend den unterschiedlichen Geschäftsanforderungen bestimmt, aber der Autor ist der Ansicht, dass das Erscheinen und Schließen der meisten Masken hauptsächlich von der Anforderung und Rückgabe der Schnittstelle abhängt. Wenn sich eine Schnittstelle im Status „Anforderung ausstehend“ befindet, wird die Maskenebene angezeigt und die Maske wird geschlossen, wenn alle Schnittstellen zurückkehren. Dieser Artikel löst hauptsächlich das Problem der Maskierung von Schnittstellenanforderungen. Er ist in ts geschrieben und listet nicht alle Details auf.

2. Design der Maskenkomponenten

Die Maskenkomponente ist eine Klasse, die die Details innerhalb der Klasse abschirmt.
(1) Die Hauptfunktion der Klasse besteht darin, Maskenebenen hinzuzufügen und zu löschen und die URL der aktuellen Anforderungsschnittstelle zu übertragen.

Klasse Maske {
 // Maskenebene anzeigen appendMask(url: string): void{}

 // Lösche die Maskenebene removeMaskl(url: string): void{}
}

(2) Fügen Sie eine Maskenebenenfunktion hinzu, rufen Sie die Funktion auf, wenn eine Anforderung gestellt wird, und übergeben Sie die aktuelle Schnittstellen-URL. Innerhalb der Funktion wird ein Überwachungsobjekt verwaltet, um zu überwachen, ob ausstehende Anforderungen vorliegen. Der Wert dieses Objekts ist die Anzahl der ausstehenden Zustände dieser Schnittstelle. Gehen Sie davon aus, dass die Maskenansichtskomponente in der Vue-Prototypenkette montiert wurde. Wenn nicht, führen Sie sie einfach über der Komponente ein.

//Definiere den Datentyp der Schnittstelle des abhörenden Objekts HTTPDictInterface {
 [Index: Zeichenfolge]: Zahl;
}

anhängenMaske(url: string): void{ 

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

 // Wenn eine Überwachungsschnittstelle vorhanden ist, zeigen Sie die Maskenebene an, if(!this.mask && Object.keys(this.monitorHTTPDict).length){

 // Fügen Sie dem Text einen Maskenebenenstil hinzu, $Mask ist die Maskenebenenstilkomponente const Constructor = Vue.extend(Vue.prototype.$Mask);
 this.mask = neuer Konstruktor().$mount();

 Dokument.Body.AnhängenUntergeordnetesElement(diese.Maske.$el);
 }
}

(3) Löschen Sie die Maskenschichtfunktion. Diese Funktion wird nach dem Ende jeder Anforderung aufgerufen. Wenn festgestellt wird, dass das Anforderungsüberwachungsobjekt leer ist, wird die Maskenschicht gelöscht. Wenn sich keine Schnittstelle im ausstehenden Zustand befindet, löschen Sie den Verbindungsschlüssel. Wenn das Objekt leer ist und über eine Maskenebene verfügt, löschen Sie die Maskenebene.

entferneMaske(URL: Zeichenfolge): void{

 // Nach erfolgreicher Rückgabe if (this.monitorHTTPDict[monitorUrl]) {
 dies.monitorHTTPDict[monitorUrl] -= 1;
 wenn (dieses.monitorHTTPDict[monitorUrl] <= 0) {
 löschen Sie dies.monitorHTTPDict[monitorUrl];
 }
 }

 // hasMask wird verwendet, um zu erkennen, ob sich auf der Seite ein Tag-Element der Maskenebene befindet, if (this.mask && this.hasMask() && !Object.keys(this.monitorHTTPDict).length) {
 Dokument.Body.RemoveChild(diese.Maske.$el);
 diese.maske = null;
 }

 dieser.timer = null;
}

3. Wie Sie diese Komponente elegant und ohne Kopplung in das Projekt einführen.

Um diese Komponente zu verwenden, müssen Sie die Funktion appendMask aufrufen, bevor alle Anforderungen initiiert werden, und die Funktion removeMask aufrufen, nachdem alle Anforderungen abgeschlossen sind. Es gibt die folgenden zwei Aufrufmethoden.
(1) Verwenden Sie den Rückruf von Komponenten wie Axios, um den Funktionsaufruf abzuschließen. Dieser Ansatz macht den Code der Mask-Komponente jedoch nicht unabhängig vom Projekt, sondern hängt von der API des jeweiligen Schnittstellenframeworks ab.

Instanz.Interceptors.Request.use((Konfiguration) => {

 // Maskenebene hinzufügen mask.appendMask(config.url);

 Konfiguration zurückgeben;
});

(2) Fügen Sie die Init-Funktion hinzu und fügen Sie den Rückruf direkt in das native XMLHttpRequest-Objekt ein. Ändern Sie die native XMLHttpRequest-Funktion und fügen Sie Callbacks in die Ereignisse „loadstart“ und „loadend“ ein. Es ist zu beachten, dass die von loadstart empfangenen Parameter nicht die URL der aktuellen Anfrage enthalten. Daher muss die Open-Funktion neu geschrieben werden, um die von open empfangene URL auf dem neuen XHR-Objekt zu mounten. Verwenden Sie diese Methode mit Vorsicht. Da das Ändern der nativen API sehr gefährlich ist und in vielen Codierungsstandards verboten ist, treten Konflikte auf, wenn jeder die native API neu schreibt, wenn diese Frameworks gleichzeitig eingeführt werden, was unvorhersehbare Folgen haben kann.

//Bestimmen Sie, ob diese Methode verwendet werden soll, indem Sie Parameter übergeben init(){
 wenn (this.autoMonitoring){
 dies.initRequestMonitor();
 }
}

// Neue Schnittstelle vom Typ xmlhttprequest NewXhrInterface erweitert XMLHttpRequest{
 requestUrl?: Zeichenfolge
}

// Native Injektion initRequestMonitor(): void{

 let OldXHR = window.XMLHttpRequest;
 lass maskClass: Maske = diese;

 // @ts-ignore, Codierungsstandards erlauben keine Änderung von XMLHttpRequest
 Fenster.XMLHttpRequest = Funktion () {

 let realXHR: NewXhrInterface = neues OldXHR();
 let oldOpen: Funktion = realXHR.open;

 realXHR.open = (...args: (Zeichenfolge | Boolescher Wert | undefiniert | null)[]): void => {

 realXHR.requestUrl = (args[1] als String);
 altOpen.apply(realXHR, args);

 };

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

 const requestUrl: string = (realXHR.requestUrl als String);

 const url: Zeichenfolge = maskClass.cleanBaseUrl(requestUrl);

 //Öffne die Maske maskClass.appendMask(url);
 });

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

 const responseURL: Zeichenfolge = (realXHR als XMLHttpRequest).responseURL;
 const url: Zeichenfolge = maskClass.cleanBaseUrl(responseURL);

 // Maske löschen maskClass.removeMask(url);
 });

 realXHR zurückgeben;
 };
}

(3) Injektionsnutzung, rufen Sie init direkt auf. Auf diese Weise werden alle Anfragen zur Änderung des Projekts über die Maske abgewickelt.

neue Maske().init()

4. So ersetzen Sie die ursprüngliche MaskShow-Methode in vorhandenen Projekten schrittweise, ohne große Probleme zu verursachen.

Bei einer direkten Anwendung im gesamten Projekt würde sich die betroffene Fläche stark ausdehnen und es würden großflächig Probleme entstehen, was kontraproduktiv wäre. Um einen reibungslosen Übergang zu gewährleisten, sollte daher ein schrittweiser Ersatzansatz gewählt werden. Die Grundidee besteht darin, durch die Konfiguration von Seiten und Blacklists zu entscheiden, auf welchen Seiten die Komponente eingeführt werden soll, sodass jedes Teammitglied sie selbst ändern kann. Schließlich ist die für die Seite verantwortliche Person diejenige, die das aktuelle Seitengeschäft am besten kennt. Ob eine Blacklist oder Whitelist erstellt wird, hängt vom spezifischen Geschäft des Projekts ab.

// Schlüssel ist die Routing-Seite, die überwacht werden muss, Wert ist ein Array, die im Array eingetragenen Schnittstellen sind auf der schwarzen Liste stehende Schnittstellen, die nicht überwacht werden müssen const PAGE_ONE = „/home“;
const PAGE_TWO = `/login`;
const HTTO_ONE = `xxx`

exportiere const maskUrlList = {
 [PAGE_ONE]: [HTTO_ONE],
 [SEITE_ZWEI]: [],
};

Die Methode appendMask filtert auf der schwarzen Liste stehende und nicht konfigurierte Seiten. maskUrlList ist das kontrollierte Objekt. Es überprüft zuerst die Seitenroute und prüft dann, ob eine Blacklist vorhanden ist.

anhängenMaske(url: string): void{

 // Pfad der aktuellen Seite abrufen, Seitenpfad abrufen und zwischen Hash- und Verlaufsmodus unterscheiden const monitorPath: string = this.getMonitorPath();

 // maskUrlList ist ein Konfigurationselement. Überprüfen Sie zuerst die Seitenroute und dann, ob eine Blacklist vorhanden ist, wenn (this.maskUrlList[monitorPath]
 && !this.maskUrlList[monitorPath].includes(url)) {
 wenn (this.monitorHTTPDict[url] === undefiniert) {
 this.monitorHTTPDict[url] = 0;
 }
 dies.monitorHTTPDict[monitorUrl] += 1;
 }

 // Maske hinzufügen layerif (!this.mask && this.hasMonitorUrl()) {
 const Konstruktor = Vue.extend(Vue.prototype.$Mask);
 this.mask = neuer Konstruktor().$mount();

 Dokument.Body.AnhängenUntergeordnetesElement(diese.Maske.$el);
 }
}

5. Einzelheiten

(1) Die Maskenebene wird nach dem Rendern geschlossen, und die eigentliche Löschlogik der Maskenebene wird im Timer platziert. Das asynchrone Rendern von Vue verwendet Promise. Wenn das Schließen also nach dem Rendern erfolgt, muss es in setTimeout platziert werden. Hierzu ist die Kenntnis der Ereignisschleife erforderlich. Wenn die Schnittstelle zurückkehrt und die Seite gerendert werden muss, wird ein Promise asynchron ausgeführt. Promise ist eine Mikrotask und setTimeout ist eine Makrotask. Wenn der Hauptthread ausgeführt wird, wird zuerst die Mikrotask ausgeführt und dann die asynchrone Makrotask setTimeout.

//Lösche die Maske layerif (!this.timer) {
 dieser.timer = window.setTimeout(() => {

 wenn (diese.mask && diese.hasMask() && !diese.hasMonitorUrl()) {
 Dokument.Body.RemoveChild(diese.Maske.$el);
 diese.maske = null;
 }

 dieser.timer = null;

 }, 0);
}

(2) „?“ zum Filtern von Schnittstellen und „#“ im Hash-Modus.

// URL der Anforderungsschnittstelle abrufen
getMonitorUrl(url: string): Zeichenfolge{
 const urlIndex: Zahl = url.indexOf(`?`);
 let monitorUrl: Zeichenfolge = URL;
 wenn (urlIndex !== -1) {
 monitorUrl = url.substring(0, urlIndex);
 }
 Monitor-URL zurückgeben;
}
// Den aktuellen Routenverlauf abrufen
getMonitorPath(): Zeichenfolge{

 const-Pfad: Zeichenfolge = this.mode === HASH_TYPE ? window.location.hash : window.location.Pfadname;

 let monitorPath: Zeichenfolge = Pfad;

 wenn (dieser.Modus === HASH_TYPE) {
 monitorPath = monitorPath.substring(Pfad.indexOf(`#`) + 1);
 }

 // Screenshot-Pfad, Anforderungsparameter löschen const hashIndex: number = monitorPath.indexOf(`?`);

 wenn (hashIndex !== -1) {
 monitorPath = monitorPath.substring(0, hashIndex);
 }

 Monitorpfad zurückgeben;
}

(3) Schnittstellenfilterung baseUrl. Wenn Sie vorsichtig sind, werden Sie feststellen, dass Sie bei Verwendung der Axios-Schnittstelle entscheiden können, ob Sie baseUrl einbringen möchten, da Axios beim Anfordern eine differenzierte Filterung durchführt. Wenn die Verwendung im frühen Stadium des Projekts nicht klar definiert ist, gibt es zwei verschiedene Möglichkeiten, Axios zu verwenden. Dann müssen Sie die Basis-URL filtern.

// BaseUrl entfernen
cleanBaseUrl(fullUrl: Zeichenfolge): Zeichenfolge {

 const baseUrlLength: Zahl = diese.baseUrl.length;
 gibt fullUrl.substring(baseUrlLength) zurück;
 
}

(4) Initialisierung der Komponente: Instanziieren Sie das Objekt durch Übergabe von Parametern.

neue Maske({
 modeType, // Hash oder Verlauf
 autoMonitoring, // Ob das native XMLHttpRequest-Objekt aktualisiert werden soll maskUrlList, // Konfigurieren Sie die importierten Seiten und Schnittstellen baseUrl, // Die BaseUrl des aktuellen Projekts
 ...
}).init()

IV. Fazit

Dieser Artikel stellt den Hintergrund, die Probleme und die Designlösungen der einheitlichen Maskenebene vor. Allerdings sind nicht alle Details aufgeführt und diese müssen auf Grundlage des tatsächlichen Geschäfts ausgewählt werden. Aber der allgemeine Plan wurde aufgeführt:
(1) Die Maskenebene soll angezeigt werden, wenn einige Schnittstellen ausstehen, und automatisch geschlossen werden, nachdem alle Schnittstellen zurückgekehrt sind. Mit Schnittstelle ist hier die Schnittstelle gemeint, die überwacht werden muss. (2) Die beiden wichtigsten Funktionen der Komponente sind appendMask zum Hinzufügen einer Maskenebene und removeMask zum Löschen einer Maskenebene.
(3) Wenn Sie möchten, dass die Maske vollständig unabhängig ist und sich nicht auf Rückrufe von einer Drittanbieterbibliothek (axios) verlassen möchten, können Sie XMLHttpRequest direkt neu schreiben. Dies ist jedoch sehr riskant und wird nicht empfohlen.
(4) Durch den Komponentenaustausch wird die Art und Weise vereinheitlicht, wie Teammitglieder ihre eigenen Routing- und Listening-Schnittstellen konfigurieren. Die Logik hierbei können Sie selbst bestimmen. Wenn viele Schnittstellen überwacht werden sollen, kann eine Blacklist verwendet werden, andernfalls eine Whitelist.
(5) Optimiertes Rendering, Anforderungsparameter und Routing-Modi.

Dies ist das Ende dieses Artikels zum Hinzufügen von Schnittstellenüberwachungsmasken in Vue-Projekten. Weitere relevante Inhalte zu Vue-Schnittstellenüberwachungsmasken finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Vue verwendet Proxy, um alle Schnittstellenstatusmethoden zu überwachen

<<:  Grundlegendes Tutorial zur Bedienung von Dateien und Berechtigungen in CentOS

>>:  Eine kurze Erläuterung der Concat-Funktion in MySQL. So fügen Sie in MySQL vor oder nach einem Feld eine Zeichenfolge hinzu

Artikel empfehlen

js Canvas zur Realisierung des Gobang-Spiels

In diesem Artikel wird der spezifische Code der L...

Vue implementiert Dialogkapselung

Inhaltsverzeichnis Vue2-Schreiben Schreiben der V...

Lösung für den MySQL-Fehlercode 1064

Wenn die Wörter in der SQL-Anweisung mit den Schl...

Beispiel für eine dynamische Sperre der IP-Blacklist von Nginx

Wenn eine Website böswillig angefragt wird, ist d...

Vue implementiert Drag & Drop für mehrspaltiges Layout

In diesem Artikel wird der spezifische Code von V...

Einführung in neue ECMAscript-Objektfunktionen

Inhaltsverzeichnis 1. Objekteigenschaften 1.1 Att...

CSS-Code zum Anordnen von Fotos in Moments

Zunächst können Sie Moments öffnen und mehrere La...

Untersuchung der MySQL-Paging-Leistung

Mehrere gängige Paging-Methoden: 1. Rolltreppenme...