Beispielanalyse des asynchronen Verhaltens von Popup-Fenstern auf Front-End-Webseiten von Vue.js

Beispielanalyse des asynchronen Verhaltens von Popup-Fenstern auf Front-End-Webseiten von Vue.js

1. Vorwort

Popup-Fenster kommen auf Webseiten sehr häufig vor, z. B. wenn Benutzer über eine Nachricht informiert werden müssen (Warnung), wenn Benutzer eine Bestätigung benötigen (Bestätigung) oder wenn Benutzer Informationen hinzufügen müssen (Eingabeaufforderung) ... Sie können sogar ein Fenster öffnen, damit Benutzer ein Formular ausfüllen können (Modaldialog).

Nachdem das Popup-Fenster angezeigt wurde, müssen Entwickler wissen, wann das Popup-Fenster geschlossen wird, um mit dem nächsten Vorgang fortzufahren.

In den älteren UI-Komponenten geschieht dies durch Ereignisrückrufe, die ungefähr so ​​aussehen:

showDialog(Inhalt, Titel, {
    geschlossen: function() { console.log("Dialogfeld wurde geschlossen"); }
})

Allerdings verhält sich das Dialogfeld. Sie sehen, es wird angezeigt, blockiert jedoch nicht den folgenden Code, und der Entwickler weiß nicht, wann es geschlossen wird, da es sich um ein Benutzerverhalten handelt. Da es asynchron ist, wäre es einfacher, es in Promise zu kapseln und mit await Syntax aufzurufen. Ein einfaches Paket könnte so aussehen:

async-Funktion asyncShowDialog(Inhalt, Titel, Optionen) {
    gib ein neues Versprechen zurück (Auflösen => {
        showDialog(Inhalt, Titel, {
            ...Optionen,
            geschlossen: gelöst
        });
    });
}
 
(asynchron () => {
    warte auf asyncShowDialog (Inhalt, Titel);
    console.log("Dialogfeld wurde geschlossen");
})();

So einfach ist das grundlegende asynchrone Verhalten des Popup-Fensters, und das war’s? Wenn Sie immer noch nicht zufrieden sind, studieren Sie weiter!

2. Finden Sie zwei Popup-Komponenten

Ant Design Vue verwendet die Form von Ereignissen. Wenn Sie auf die Schaltfläche "OK" klicken, wird das ok -Ereignis ausgelöst, und wenn Sie auf "Abbrechen" oder die Schaltfläche "Schließen" in der oberen rechten Ecke klicken, wird das cancel ausgelöst.

Diese beiden Ereignisbehandlungsfunktionen werden über onOk und onCancel des Parameterobjekts bereitgestellt. Es sieht schlicht aus, aber wenn der Eventhandler ein Promise-Objekt zurückgibt, erscheint nach dem Klicken auf die Schaltfläche eine Ladeanimation und das Dialogfeld wird erst geschlossen, wenn das Promise-Objekt fertig ist. Dieses Design kombiniert die asynchrone Warteanimation mit dem Popup-Fenster. Es ist einfach und intuitiv und der Code lässt sich auch leicht schreiben. Nehmen Sie das Bestätigungsdialogfeld als Beispiel:

Modal.bestätigen({
    ...
    beiOk() {
        // Nach dem Klicken auf die Schaltfläche "OK" wird die Ladeanimation angezeigt und das Dialogfeld wird nach einer Sekunde geschlossen return new Promise(resolve => {
            setTimeout(auflösen, 1000);
        });
    }
    ...
});

Element Plus verwendet das Promise-Format. Beim Öffnen des Dialogfelds wird die Bestätigungs- oder Stornierungsverarbeitungsfunktion nicht als Parameter übergeben, sondern direkt ein Promise-Objekt zurückgegeben, das Entwickler über .then()/.catch() oder await verarbeiten können. Beispiel:

versuchen {
    warte auf ElMessageBox.confirm(...);
    //Drücken Sie die OK-Taste, um es hier zu verarbeiten} catch(err) {
    // Das Drücken der Abbrechen-Taste wird hier verarbeitet }

Die Element Plus-Verarbeitungsmethode erfordert, dass die Geschäftsabwicklung erst nach Schließen des Dialogfelds durchgeführt werden kann. Dies ist auch die Einschränkung bei der Verwendung von Promise – es ist schwierig, neue Logik in ein bereits gekapseltes Promise-Objekt einzufügen.

Wenn Sie vor dem Schließen ElMessageBox einige asynchrone Vorgänge ausführen möchten, wie es Ant Design tut, können Sie nur danach suchen, um zu sehen, ob es vor dem Schließen Verarbeitungsereignisse bereitstellt. Ich habe es tatsächlich gefunden, nachdem ich eine Weile gesucht hatte. Es hat beforeClose -Ereignis. Die Signatur des Ereignishandlers lautet beforeClose(action, instance, done) :

action gibt an, welche Schaltfläche gedrückt wurde, und mögliche Werte sind "confirm" , "cancel" und "close" (keine Erklärung erforderlich).

instance ist eine MessageBox-Instanz, die zur Steuerung einiger Schnittstelleneffekte verwendet werden kann, wie z. B.

instance.confirmButtonLoading = true zeigt eine Ladeanimation auf der Schaltfläche „OK“ an, instance.confirmButtonText kann verwendet werden, um den Schaltflächentext zu ändern … Diese Vorgänge können beim asynchronen Warten eine bessere Benutzererfahrung bieten.

done ist eine Funktion, die aufgerufen wird, um anzuzeigen, dass die asynchrone Verarbeitung von beforeClose() abgeschlossen ist und das Dialogfeld jetzt geschlossen werden kann!

Daher kann die Ant Design-ähnliche Verarbeitung wie folgt geschrieben werden:

versuchen {
    warte auf ElMessageBox.confirm({
        ...
        beforeClose: async (Aktion, Instanz, erledigt) => {
            warte auf neues Promise(resolve => setTimeout(resolve, 1000));
            Erledigt();
        }
    });
    //Drücken Sie die OK-Taste, um es hier zu verarbeiten} catch(err) {
    // Das Drücken der Abbrechen-Taste wird hier verarbeitet }

3. Machen Sie selbst eins

Nach der Analyse der Verhaltensverarbeitung der beiden Bulletbox-Komponenten wissen wir bereits, dass eine Bulletbox-Komponente mit guter Erfahrung die folgenden Eigenschaften aufweisen sollte:

  • Bereitstellung von Promise-basierten asynchronen Steuerungsfunktionen (Ant Design Vue bietet dies nicht, es kann jedoch wie in der „Sequenz“ gekapselt werden).
  • Ermöglicht die Ausführung einiger Vorgänge vor dem Schließen, auch asynchroner Vorgänge.
  • Geben Sie während des asynchronen Ladevorgangs Schnittstellenfeedback und fordern Sie am besten keine Entwicklersteuerung an (aus dieser Sicht ist Ant Design bequemer als Element Plus).

Als Nächstes schreiben wir selbst eines und sehen, wie die oben genannten Funktionen implementiert werden. Da wir jedoch hauptsächlich Verhalten und nicht Datenverarbeitung untersuchen, verwenden wir nicht das Vue-Framework, sondern direkt DOM-Operationen und führen dann jQuery ein, um die DOM-Verarbeitung zu vereinfachen.

Auch das HTML-Skelett des Dialogfelds ist relativ einfach: Unten eine Maskenebene, darüber eine <div> -Ebene mit fester Größe und das interne <div> ist in drei Bereiche unterteilt: Titel, Inhalt und Bedienbereich:

<div Klasse="Dialog" id="Dialogvorlage">
  <div Klasse="Dialogfenster">
    <div class="dialog-title">Dialogfeldtitel</div>
    <div class="dialog-content">Dialoginhalt</div>
    <div Klasse="Dialogoperation">
      <button type="button" class="ensure-button">Bestätigen</button>
      <button type="button" class="cancel-button">Abbrechen</button>
    </div>
  </div>
</div>

Hier wird es als Vorlage definiert und wir hoffen, jedes Mal zur Präsentation einen DOM daraus zu klonen und ihn beim Schließen zu zerstören.

Der Inhalt des Stylesheets ist lang und kann über den Beispiellink unten abgerufen werden. Der Code und seine Entwicklung stehen im Mittelpunkt dieses Artikels.

Die einfachste Möglichkeit zur Darstellung besteht darin, es mit jQuery zu klonen und anzuzeigen. Denken Sie jedoch vor der Anzeige daran, id -Attribut zu löschen und es zu <body> hinzuzufügen:

$("#dialogTemplate").clone().removeAttr("id").appendTo("body").show();

Packen Sie es in eine Funktion ein und fügen Sie eine Verarbeitung für die Schaltflächen „OK“ und „Abbrechen“ hinzu:

Funktion showDialog(Inhalt, Titel) {
    const $dialog = $("#dialogTemplate").clone().removeAttr("id"); 
    // Titel und Inhalt des Dialogfelds festlegen (einfaches Beispiel, behandelt also nur Text)
    $dialog.find(".dialog-title").text(Titel);
    $dialog.find(".dialog-content").text(Inhalt); 
    // Zwei Schaltflächenereignisse über Ereignisproxy verarbeiten (oder ohne Proxy) $dialog
        .on("klicken", ".ensure-button", () => {
            $dialog.entfernen();
        })
        .on("klicken", ".abbrechen-button", () => {
            $dialog.entfernen();
        }); 
    $dialog.appendTo("body").anzeigen();
}

Die grundlegende Logik des Popup-Fensters wird offenbart. Nehmen wir nun zwei Optimierungen vor: ① Kapseln Sie $dialog.remove() in eine Funktion, um die einheitliche Verarbeitung des Schließens von Dialogfeldern zu ermöglichen (Code-Wiederverwendung). ② Die Verwendung von .show() ist zu abrupt, ändern Sie es daher fadeIn(200) ; analog sollte fadeOut(200) vor .remove() aufgerufen werden.

Funktion zeigeDialog(...) {
    ... 
    const zerstören = () => {
        $dialog.fadeOut(200, () => $dialog.remove());
    }; 
    $dialog
        .on("klicken", ".ensure-button", zerstören)
        .on("klicken", ".abbrechen-Schaltfläche", zerstören); 
    $dialog.appendTo("body").fadeIn(200);
}

3.1. Verkapselung von Versprechen

An diesem Punkt kann das Popup-Fenster normal geöffnet/geschlossen werden, es gibt jedoch keine Möglichkeit, den Logikcode „OK“ oder „Abbrechen“ einzufügen. Wie bereits erwähnt, kann die Schnittstelle in zwei Formen bereitgestellt werden: Ereignisse oder Versprechen. Hier wird die Promise-Methode verwendet. Wenn Sie auf „OK“ klicken, wird das Problem behoben, und wenn Sie auf „Abbrechen“ klicken, wird es abgelehnt.

Funktion zeigeDialog(...) {
    ... 
    const promise = neues Versprechen((lösen, ablehnen) => {
        $dialog
            .on("klicken", ".ensure-button", () => {
                zerstören();
                lösen("ok");
            })
            .on("klicken", ".abbrechen-button", () => {
                zerstören();
                ablehnen("abbrechen");
            });
    }); 
    $dialog.appendTo("body").fadeIn(200);
    Versprechen zurückgeben();
}

Die Kapselung ist abgeschlossen, es gibt jedoch ein Problem: destroy() ist ein asynchroner Prozess, der Code wartet jedoch nicht auf dessen Abschluss. Nachdem showDialog() die asynchrone Verarbeitung abgeschlossen hat, werden daher weiterhin die Vorgänge fadeOut() und remove() ausgeführt. Um dieses Problem zu lösen, können Sie destory() nur kapseln. Vergessen Sie natürlich nicht, beim Aufrufen await hinzuzufügen. Um await hinzuzufügen, müssen Sie die äußere Funktion als async deklarieren:

Funktion zeigeDialog(...) {
    ...
    const zerstören = () => {
        gib ein neues Versprechen zurück (Auflösen => {
            $dialog.fadeOut(200, () => {
                $dialog.entfernen();
                lösen();
            });
        });
    };
     const promise = neues Versprechen((lösen, ablehnen) => {
        $dialog
            .on("klicken", ".ensure-button", async () => {
                warte auf Zerstörung();
                lösen("ok");
            })
            .on("klicken", ".abbrechen-button", async () => {
                warte auf Zerstörung();
                ablehnen("abbrechen");
            });
    }); 
    ...
}

3.2. Erlaube asynchrones Warten, wenn bestimmte

Unabhängig davon, ob Sie auf „Bestätigen“ oder „Abbrechen“ klicken, kann das Popup-Fenster für das asynchrone Warten angezeigt bleiben. Exemplarisch wird hier aber nur der „OK“-Fall behandelt.

Dieser asynchrone Wartevorgang muss in das Popup-Fenster eingefügt werden und kann nur in Form von Parametern eingefügt werden. Daher müssen Sie showDialog() einen options hinzufügen, damit eine Verarbeitungsfunktion in onOk eingefügt werden kann. Wenn diese Verarbeitungsfunktion Promise Like zurückgibt, wird asynchron gewartet.

Ändern Sie zuerst showDialog() :

Funktion showDialog(Inhalt, Titel, Optionen = {}) { ... }

Behandeln Sie dann das Ereignis $dialog.on("click", ".ensure-button", ...):

$dialog
    .on("klicken", ".ensure-button", async () => {
        const { onOk } = Optionen;
        // onOk aus den Optionen holen. Wenn es eine Funktion ist, muss sie auf die Verarbeitung warten, wenn (typeof onOk === "function") {
            const r = onOk();
            // Bestimme, ob das Ergebnis von onOk() ein Promise-ähnliches Objekt ist // Nur Promise-ähnliche Objekte benötigen asynchrones Warten if (typeof r?.then === "function") {
                const $button = $dialog.find(".ensure-button");
                // Während des asynchronen Wartevorgangs muss dem Benutzer eine Rückmeldung gegeben werden. // Ich bin hier faul und verwende keine Ladeanimation, sondern nur Text für die Rückmeldung. $button.text("Wird verarbeitet …");
                warte auf r;
                // Denn nach Abschluss erfolgt vor dem Schließen ein 200 Millisekunden langer Ausblendvorgang,
                // Daher ist es notwendig, den Buttontext in „Fertig“ zu ändern, um den Benutzern rechtzeitig Feedback zu geben. $button.text("Fertig");
            }
        }
        warte auf Zerstörung();
        lösen("ok");
    })

Nun wird das Verhalten dieses Popup-Fensters grundsätzlich verarbeitet. Das aufrufende Beispiel lautet:

const Ergebnis = warte auf ShowDialog(
    „Hallo, hier ist der Inhalt des Dialogfelds“,
    "Sag Hallo",
    {
        onOk: () => neues Versprechen((auflösen) => { setTimeout(auflösen, 3000); })
    }
).catch(msg => msg); // Hier wird die durch die Stornierung verursachte Ablehnung in eine Lösung umgewandelt, um die Verwendung von try...catch... zu vermeiden.
 
console.log(result === "ok" ? "OK drücken" : "Abbrechen drücken");

3.3. Verbessern Sie die Details

Es ist etwas unpassend, console.log(...) am Ende des Dialogfelds zu verwenden. Wäre es nicht besser, direkt eine Eingabeaufforderung anzuzeigen?

Aber jetzt verarbeitet showDialog() nur das Popup-Fenster „Bestätigen“, nicht das Popup-Fenster „Warnung“ … Das ist kein großes Problem, fügen Sie einfach einen type in options hinzu. Wenn type "alert" ist, entfernen Sie die Schaltfläche „Abbrechen“.

asynchrone Funktion showDialog(Inhalt, Titel, Optionen = {}) {
    ...
    
    wenn (Optionen.Typ === "Alarm") {
        $dialog.find(".abbrechen-button").entfernen();
    }    
    ...
}

Anschließend kann das endgültige console.log(...) erstellt werden:

showDialog(result === "ok" ? "OK drücken" : "Abbrechen drücken", "Prompt", { type: "alert" });

3.4. Reform

Wenn Sie die Verarbeitungsfunktion nicht in options einfügen möchten, können Sie sie auch in das zurückgegebene Promise-Objekt einfügen. Ändern Sie zunächst im Ereignis .ensure-button const { onOk } = options in const { onOk } = promise , holen Sie das eingefügte onOk aus promise . Ändern Sie dann den aufrufenden Teil:

const dialog = showDialog("Hallo, hier ist der Inhalt des Dialogfelds", "Sag Hallo");
// Fügen Sie die Verarbeitungsfunktion in das onOk des Versprechens ein
dialog.onOk = () => neues Promise((auflösen) => { setTimeout(auflösen, 3000); });
const Ergebnis = warte auf Dialog.catch(msg => msg);
showDialog(result === "ok" ? "OK drücken" : "Abbrechen drücken", "Prompt", { type: "alert" });

Dabei sind einige Dinge zu beachten:

dialog darf nur direkt von showDialog() zurückgegeben werden. Wenn .catch() aufgerufen wird, wird ein weiteres Promise-Objekt abgerufen. Zu diesem Zeitpunkt kann onOk es nicht in das in showDialog() generierte Promise-Objekt einfügen.

showDialog() kann nicht als async deklariert werden, da sonst das zurückgegebene Promise-Objekt nicht das darin generierte ist.

Vergessen Sie nicht, await .

Oben finden Sie eine detaillierte Analyse des Beispiels für das asynchrone Verhalten des Popup-Fensters der Front-End-Webseite von vue.js. Weitere Informationen zum asynchronen Popup-Fenster der Front-End-Webseite von vue.js finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • Einige gängige Popup-Fenster/Drag & Drop/asynchroner Dateiupload und andere praktische Codes
  • Ideen und Implementierungscode für das seitliche Popup-Fenster einer mit Javascript erstellten Webseite
  • Asynchroner Anmeldeeffekt der Popup-Ebene mit jQuery+Ajax+PHP (mit Quellcode-Download)
  • Analyse der asynchronen innerHTML-Nutzung von JavaScript
  • JS implementiert die Methode zum Einblenden eines Eingabefelds auf der Webseite

<<:  Eine großartige Sammlung von Lernressourcen zu Webstandards

>>:  CSS3 benutzerdefinierter Bildlaufleistenstil::webkit-scrollbar Beispielcode, ausführliche Erklärung

Artikel empfehlen

Detaillierte Schritte zur Installation des NERDTree-Plugins in Vim unter Ubuntu

NERDTree ist ein Dateisystembrowser für Vim. Mit ...

Grafisches Tutorial zur Installation von MySQL5.7.18 im Windows-System

MySQL-Installationstutorial für Windows-Systeme h...

js implementiert einen einfachen Rechner

Verwenden Sie natives JS, um einen einfachen Rech...

Grafisches Tutorial zur Installation und Konfiguration von MySQL 5.7.25

Es gibt zwei Arten von MySQL-Installationsdateien...

Teilen Sie 13 hervorragende Web-Wireframe-Design- und Produktionstools

Wenn Sie mit der Arbeit an einem Projekt beginnen...

Detaillierte Schritte zur Installation von MYSQL8.0 auf CentOS7.6

1. Im Allgemeinen ist MariaDB in CentOS standardm...

Detaillierte Erläuterung des mobilen Projekts vite2.0 + vue3

1. Technische Punkte Vite-Version vue3 ts Integri...

Empfehlen Sie einige nützliche Lernmaterialien für Neulinge im Webdesign

Viele Leute haben mich auch gefragt, welche Büche...

Detaillierte Erläuterung der elastischen CSS3-Erweiterungsbox

verwenden Flexible Boxen spielen beim Front-End-L...

Die Verwendung des V-Modells in Vue3-Komponenten und ausführliche Erklärung

Inhaltsverzeichnis Verwenden Sie bidirektionale B...