AnimationsvorschauIch arbeite gerade an meinem Abschlussprojekt. Ich möchte dem Abschlussprojektsystem ein seitliches Nachrichteneingabefeld ähnlich dem Apple-System hinzufügen. Schauen wir uns zuerst die Wirkung an. Andere UI-BibliothekenStudierende, die mit Front-End-Entwicklung vertraut sind, haben möglicherweise entdeckt, dass diese Komponente in Element UI „Notification“ und in Bootstrap „Toasts“ heißt. StartAls ich diese Komponente zum ersten Mal sah, fand ich sie sehr cool. Heute zeige ich Ihnen Schritt für Schritt, wie ich sie implementiert habe. Wenn es Fehler oder Bereiche gibt, die optimiert werden können, kommentieren Sie bitte. 🥳 (Diese Komponente wird basierend auf Vue3 implementiert) Komponentenverzeichnisstruktur
toasts.vueUngefähre DOM-Struktur<!-- Popup-Fenster --> <div Klasse="Toast-Container"> <!-- Symbol Symbol --> <Vorlage> ... </Vorlage> <!-- Hauptinhalt --> <div Klasse="Toast-Inhalt"> <!-- Titel und Countdown --> <div Klasse="Toastkopf"> ... </div> <!-- Text --> <div Klasse = "Toast-Body" >...</div> <!-- Aktionsschaltfläche --> <div Klasse="Toast-Operieren"> ... </div> </div> <!-- Schließen --> <div Klasse="Toast-schließen"> <i class="fi fi-rr-cross-small"></i> </div> </div> index.jsKomponenten registrieren und globale Variablen definierenHier registrieren wir die Komponente und definieren globale Variablen für den Aufruf Toast aus „./instance“ importieren Toast aus „./toasts.vue“ importieren exportiere Standard (App) => { //Komponente registrieren app.component(Toast.name, Toast); // Globale Variablen registrieren, dann einfach $Toast({}) aufrufen app.config.globalProperties.$Toast = toast; } Instanz.jsManuelles Mounten einer Instanz🌟🌟🌟 Hier ist der Kernpunkt des vollständigen Artikels🌟🌟🌟 Lassen Sie uns zunächst lernen, wie Sie Komponenten manuell auf der Seite einbinden. importiere { createApp } aus „vue“; Toasts aus „./toasts“ importieren const toasts = (Optionen) => { //Erstellen Sie einen übergeordneten Container let root = document.createElement('div'); Dokument.Body.AppendChild(Stamm) // Eine Toasts-Instanz erstellen let ToastsConstructor = createApp(Toasts, options) // Das übergeordnete Element mounten let instance = ToastsConstructor.mount(root) // Werfen Sie die Instanz selbst nach vue Rückgabeinstanz } Standard-Toasts exportieren; Richtige Positionierung für jeden Toast Wie in der Abbildung gezeigt, wird jeder erstellte Toast unterhalb des vorherigen Toasts angeordnet (der Abstand beträgt hier 16px). Um diesen Effekt zu erzielen, müssen wir die Höhe der vorhandenen Toasts kennen. // Instanz.js // Hier müssen wir ein Array definieren, um die aktuell aktiven Toasts zu speichern let Instanzen = [] const toasts = (Optionen) => { ... // Nach der Erstellung die Instanz zum Array hinzufügen instances.push(instance) //Höhe zurücksetzen let verticalOffset = 0 // Durchlaufe und rufe die Höhe der aktuell vorhandenen Toasts und ihrer Lückenakkumulationsinstanzen ab.forEach(item => { vertikaler Versatz += item.$el.offsetHeight + 16 }) // Akkumulieren Sie die erforderliche Lücke verticalOffset += 16 // Weisen Sie der aktuellen Instanz die Länge der Y-Achse zu instance.toastPosition.y = verticalOffset ... } Standard-Toasts exportieren; Aktive und zeitgesteuerte Abschaltfunktion hinzugefügt Lassen Sie uns zunächst das Geschäft hier analysieren:
Auf dieser Grundlage können wir einige humanisierte Vorgänge hinzufügen, z. B. das Stoppen des automatischen Schließens eines Toasts, wenn die Maus hineinbewegt wird (andere Toasts sind davon nicht betroffen) und das erneute Aktivieren des automatischen Schließens, wenn die Maus herausbewegt wird. <!-- toasts.vue --> <Vorlage> <transition name="toast" @after-leave="nachVerlassen" @after-enter="nachEintreten"> <div ref="container" class="toast-container" :style="toastStyle" v-show="sichtbar" @mouseenter="clearTimer" @mouseleave="createTimer"> ... <!-- Schließen --> <div Klasse="toast-close" @click="Zerstörung"> <i class="fi fi-rr-cross-small"></i> </div> </div> </Übergang> </Vorlage> <Skript> Bus aus „./toastsBus“ importieren importiere {ref, berechnet, onMounted, onBeforeUnmount} aus 'vue' Standard exportieren { Requisiten: { // Automatische Abschaltzeit (in Millisekunden) autoClose: { Typ: Nummer, Standard: 4500 } }, setup(Eigenschaften){ // Ob angezeigt werden soll const visible = ref(false); //Toast-Containerinstanz const container = ref(null); // Die Höhe des Toasts selbst const height = ref(0); // Toastposition const toastPosition = ref({ x: 16, J: 16 }) const toastStyle = berechnet(()=>{ zurückkehren { oben: `${toastPosition.value.y}px`, rechts: `${toastPosition.value.x}px`, } }) //Toast-ID const id = ref('') //Nachdem der Toast die Animation verlässt, Funktion afterLeave(){ // Sagen Sie instance.js, dass es geschlossen werden muss() Bus.$emit('geschlossen',id.value); } //Nachdem der Toast in die Animation eintritt, Funktion afterEnter(){ Höhe.Wert = Container.Wert.OffsetHöhe } // Zeitgeber const timer = ref(null); // Maus betritt Toast Funktion clearTimer(){ wenn(Timer.Wert) Zeitüberschreitung löschen(Timer.Wert) } //Maus aus Toast Funktion createTimer(){ wenn(props.autoClose){ timer.value = setTimeout(() => { sichtbarer Wert = false }, props.autoClose) } } //Zerstörungsfunktion destruction(){ sichtbarer Wert = false } beim Montieren(()=>{ erstelleTimer(); }) beiVorUnmount(()=>{ wenn(Timer.Wert) Zeitüberschreitung löschen(Timer.Wert) }) zurückkehren { sichtbar, Container, Höhe, ToastPosition, ToastStil, Ausweis, nachVerlassen, nach der Eingabetaste, Timer, Zeitgeber löschen, erstelleTimer, Zerstörung } } } </Skript> Lassen Sie uns die Logik des Toast-Schließens in instance.js analysieren
// Instanz.js importiere { createApp } von „vue“; Toasts aus „./toasts“ importieren Bus aus „./toastsBus“ importieren let Instanzen = [] lass seed = 1 const toasts = (Optionen) => { // Manuell eine Instanz mounten let ToastsConstructor = createApp(Toasts, options) let-Instanz = ToastsConstructor.mount(root) // Der Instanz eine eindeutige Kennung hinzufügen instance.id = id // Instanz anzeigen instance.visible = true ... // Warten Sie auf das Abschlussereignis von toasts.vue Bus.$on('closed', (id) => { // Da hier alle 'geschlossenen' Ereignisse überwacht werden, muss die ID übereinstimmen, um sicherzustellen, dass if (instance.id == id) { //Löschlogik aufrufen removeInstance(instance) // Lösche das DOM-Element auf <body> document.body.removeChild(root) //Zerstöre die Instanz ToastsConstructor.unmount(); } }) Instanzen.push(Instanz) Rückgabeinstanz } Standard-Toasts exportieren; // Löschlogik const removeInstance = (Instanz) => { wenn (!Instanz) return let len = Instanzen.Länge // Finde den Index, der zerstört werden muss const index = instances.findIndex(item => { Rückgabewert: item.id === instance.id }) // Instanzen aus dem Array entfernen.splice(index, 1) // Wenn im aktuellen Array noch Toasts vorhanden sind, müssen Sie die folgenden Toasts durchlaufen und nach oben verschieben und die Verschiebung neu berechnen, wenn (Länge <= 1) returniert wird. // Höhe der gelöschten Instanz abrufen const h = instance.height // Durchlaufe die Toasts, die nach der gelöschten Instanz indiziert sind für (sei i = Index; i < Länge - 1; i++) { // Formel: Die überlebende Instanz subtrahiert die gelöschte Höhe und ihre Lückenhöhe von ihrem Y-Achsen-Offset instances[i].toastPosition.y = parseInt(instances[i].toastPosition.y - h - 16) } } Vollständiger Codeindex.js Toast aus „./instance“ importieren Toast aus „./toasts.vue“ importieren exportiere Standard (App) => { app.komponente(Toast.name, Toast); app.config.globalProperties.$Toast = toast; } toastsBus.js Emitter von „Tiny-Emitter/Instance“ importieren Standard exportieren { $auf: (...args) => emitter.auf(...args), $once: (...args) => emitter.once(...args), $aus: (...args) => emitter.aus(...args), $emit: (...args) => emitter.emit(...args) } Instanz.js importiere { createApp } aus „vue“; Toasts aus „./toasts“ importieren Bus aus „./toastsBus“ importieren let Instanzen = [] lass seed = 1 const toasts = (Optionen) => { //Erstellen Sie einen übergeordneten Container const id = `toasts_${seed++}` let root = document.createElement('div'); root.setAttribute('Daten-ID', ID) Dokument.Body.AppendChild(Stamm) let ToastsConstructor = createApp(Toasts, Optionen) let-Instanz = ToastsConstructor.mount(root) Instanz-ID = ID Instanz.sichtbar = true //Höhe zurücksetzen let verticalOffset = 0 Instanzen.fürJedes(Element => { vertikaler Versatz += item.$el.offsetHeight + 16 }) vertikaler Versatz += 16 Instanz.toastPosition.y = vertikaler Offset Bus.$on('geschlossen', (id) => { wenn (Instanz.id == ID) { entferneInstanz(Instanz) Dokument.Body.RemoveChild(Wurzel) ToastsConstructor.unmount(); } }) Instanzen.push(Instanz) Rückgabeinstanz } Standard-Toasts exportieren; const removeInstance = (Instanz) => { wenn (!Instanz) return let len = Instanzen.Länge const index = Instanzen.findIndex(item => { Rückgabewert: item.id === instance.id }) Instanzen.splice(Index, 1) wenn (Länge <= 1) return const h = Instanzhöhe für (sei i = Index; i < Länge - 1; i++) { Instanzen[i].toastPosition.y = parseInt(Instanzen[i].toastPosition.y - h - 16) } } toast.vue Fügen Sie ein paar Details hinzu, beispielsweise ein anpassbares Symbol oder Bild, eine Schaltfläche zum Abbrechen des Schließens, legen Sie eine Zeit für das automatische Schließen fest oder deaktivieren Sie die Funktion zum automatischen Schließen. <Vorlage> <transition name="toast" @after-leave="nachVerlassen" @after-enter="nachEintreten"> <!-- Popup-Fenster --> <div ref="container" class="toast-container" :style="toastStyle" v-show="sichtbar" @mouseenter="clearTimer" @mouseleave="createTimer"> <!-- Symbol --> <template v-if="Typ || Typ != 'benutzerdefiniert' || Typ != 'img'"> <div Klasse="Toast-Icon Erfolg" v-if="Typ==='Erfolg'"> <i class="fi fi-br-check"></i> </div> <div Klasse="Toast-Icon-Warnung" v-if="Typ==='Warnung'"> ? </div> <div Klasse="Toast-Symbolinfo" v-if="Typ==='info'"> <i class="fi fi-sr-bell-ring"></i> </div> <div Klasse="Toast-Icon-Fehler" v-if="Typ==='Fehler'"> <i class="fi fi-br-cross-small"></i> </div> </Vorlage> <div :style="{'backgroundColor': customIconBackground}" class="toast-icon" v-if="type==='custom'" v-html="customIcon"></div> <img Klasse = "toast-custom-img": src = "customImg" v-if = "Typ === 'img'"/> <!-- Inhalt --> <div Klasse="Toast-Inhalt"> <!-- Kopf --> <div Klasse="Toastkopf" v-if="Titel"> <!-- Titel --> <span class="toast-title">{{Titel}}</span> <!-- Zeit --> <span class="toast-countdown">{{countDown}}</span> </div> <!-- Text --> <div Klasse="toast-body" v-if="Nachricht" v-html="Nachricht"></div> <!-- bedienen --> <div Klasse="Toast-Operieren"> <a Klasse = "Toast-Button-Bestätigen" :Klasse="[{'Erfolg':Typ==='Erfolg'}, {'Warnung':Typ==='Warnung'}, {'info':Typ==='info'}, {'error':type==='error'}]">{{confirmText}}</a> </div> </div> <!-- Schließen --> <div v-if="closeIcon" Klasse="toast-close" @click="Zerstörung"> <i class="fi fi-rr-cross-small"></i> </div> </div> </Übergang> </Vorlage> <Skript> Bus aus „./toastsBus“ importieren importiere {ref, berechnet, onMounted, onBeforeUnmount} aus 'vue' Standard exportieren { Requisiten: { Titel: String, SchließenIcon: { Typ: Boolean, Standard: true }, Nachricht: String, Typ: { Typ: Zeichenfolge, Validator: Funktion (Wert) { return ['Erfolg', 'Warnung', 'Info', 'Fehler', 'Benutzerdefiniert', 'Bild'].includes(val); } }, Bestätigungstext: Zeichenfolge, benutzerdefiniertes Symbol: Zeichenfolge, benutzerdefiniertesSymbolHintergrundbild: Zeichenfolge, benutzerdefiniertesBild: Zeichenfolge, autoClose: { Typ: Nummer, Standard: 4500 } }, setup(Eigenschaften){ // Anzeige const sichtbar = ref(false); //Containerinstanz const container = ref(null); // Höhe const height = ref(0); // Position const toastPosition = ref({ x: 16, J: 16 }) const toastStyle = berechnet(()=>{ zurückkehren { oben: `${toastPosition.value.y}px`, rechts: `${toastPosition.value.x}px`, } }) // Countdown const countDown = berechnet(()=>{ returniere 'vor 2 Sekunden' }) const id = ref('') // Nach dem Verlassen der Funktion afterLeave(){ Bus.$emit('geschlossen',id.value); } // Nach dem Aufrufen der Funktion afterEnter(){ Höhe.Wert = Container.Wert.OffsetHöhe } // Zeitgeber const timer = ref(null); // Maus betritt Funktion clearTimer(){ wenn(Timer.Wert) Zeitüberschreitung löschen(Timer.Wert) } //Maus raus Funktion createTimer(){ wenn(props.autoClose){ timer.value = setTimeout(() => { sichtbarer Wert = false }, props.autoClose) } } //Zerstörungsfunktion destruction(){ sichtbarer Wert = false } beim Montieren(()=>{ erstelleTimer(); }) beiVorUnmount(()=>{ wenn(Timer.Wert) Zeitüberschreitung löschen(Timer.Wert) }) zurückkehren { sichtbar, ToastPosition, ToastStil, Countdown, nachVerlassen, nach der Eingabetaste, Zeitgeber löschen, erstelleTimer, Timer, Zerstörung, Container, Höhe, Ausweis } } } </Skript> <style lang="scss" scoped> //Externer Container.Toast-Container{ Breite: 330px; Box-Schatten: rgba(0, 0, 0, 0,1) 0px 2px 12px 0px; Hintergrundfarbe: rgba(#F7F7F7, .6); Rand: 1px durchgezogen #E5E5E5; Polsterung: 14px 13px; Z-Index: 1001; Position: fest; oben: 0; rechts: 0; Rahmenradius: 10px; Hintergrundfilter: Unschärfe (15px); Anzeige: Flex; Elemente ausrichten: strecken; Übergang: alle 0,3 Sekunden mühelos; wird sich ändern: oben, links; } //--------------Symbol-------------- .toast-Symbol, .toast-schließen{ Flex-Schrumpfen: 0; } .Toast-Symbol{ Breite: 30px; Höhe: 30px; Randradius: 100 %; Anzeige: Inline-Flex; Elemente ausrichten: zentrieren; Inhalt ausrichten: zentriert; } // Richtig.toast-icon.success{ Hintergrundfarbe: rgba (#2BB44A, .15); Farbe: #2BB44A; } //Ausnahme.toast-icon.warning{ Hintergrundfarbe: rgba(#ffcc00, .15); Farbe: #F89E23; Schriftstärke: 600; Schriftgröße: 18px; } // Fehler.toast-icon.error{ Schriftgröße: 18px; Hintergrundfarbe: rgba(#EB2833, .1); Farbe: #EB2833; } // information.toast-icon.info{ Hintergrundfarbe: rgba(#3E71F3, .1); Farbe: #3E71F3; } // Benutzerdefiniertes Bild.toast-custom-img{ Breite: 40px; Höhe: 40px; Rahmenradius: 10px; Überlauf: versteckt; Flex-Schrumpfen: 0; } // ------------- Inhalt ----------- .toast-Inhalt{ Polsterung: 0,8px, 0,13px; biegen: 1; } //-------------- Kopf -------------- .toast-kopf{ Anzeige: Flex; Elemente ausrichten: zentrieren; Inhalt ausrichten: Abstand dazwischen; } //Titel .toast-Titel{ Schriftgröße: 16px; Zeilenhöhe: 24px; Farbe: #191919; Schriftstärke: 600; Überlauf: versteckt; Textüberlauf: Auslassungspunkte; Leerzeichen: Nowrap; } // Zeit .toast-countdown{ Schriftgröße: 12px; Farbe: #929292; Zeilenhöhe: 18,375px; } //-------------- Körper ----------- .toast-body{ Farbe: #191919; Zeilenhöhe: 21px; Polsterung oben: 5px; } //---------- schließen ------- .toast-schließen{ Polsterung: 3px; Cursor: Zeiger; Schriftgröße: 18px; Breite: 24px; Höhe: 24px; Rahmenradius: 8px; Anzeige: Inline-Flex; Elemente ausrichten: zentrieren; Inhalt ausrichten: zentriert; } .toast-close:hover{ Hintergrundfarbe: rgba(#E4E4E4, .5); } // --------- betreiben ---------- .toast-button-confirm{ Schriftstärke: 600; Farbe: #3E71F3; } .toast-button-confirm:hover{ Farbe: #345ec9; } // Erfolg.toast-button-confirm.success{ Farbe: #2BB44A; } .toast-button-confirm.success:hover{ Farbe: #218a3a; } //Ausnahme.toast-button-confirm.warning{ Farbe: #F89E23; } .toast-button-confirm.warning:hover{ Farbe: #df8f1f; } // information.toast-button-confirm.info{ Farbe: #3E71F3; } .toast-button-confirm.info:hover{ Farbe: #345ec9; } // Fehler.toast-button-confirm.error{ Farbe: #EB2833; } .toast-button-confirm.error:hover{ Farbe: #c9101a; } /* Animation */ .toast-enter-from, .toast-verlassen-zu{ transformieren: übersetzenX(120%); } .v-verlassen-von, .toast-enter-to{ transformieren: übersetzenX(00%); } </Stil> Haupt-JS importiere { createApp } von 'vue' App aus „./App.vue“ importieren const app = createApp(App) importiere '@/assets/font/UIcons/font.css' // Toasts installieren Toasts aus „./components/toasts“ importieren app.verwenden(toasts).mount('#app') verwenden <Vorlage> <button @click="clickHandle">Senden</button> </Vorlage> <Skript> importiere { getCurrentInstance } von 'vue' Standard exportieren { aufstellen(){ const Instanz = getCurrentInstance() Funktion KlickHandle(){ // Es ist eine Schande, hier die globalen Variablen von vue3 aufzurufen. Ich weiß nicht, ob ihr noch andere gute Ideen habt.instance.appContext.config.globalProperties.$Toast({ Typ: "Info", Titel: 'Dies ist ein Titel', Nachricht: ‚Dieser Artikel soll die Hauptlogik der Mount-Funktion klären und den grundlegenden Verarbeitungsablauf verdeutlichen (Vue-Version 3.1.1). ' }) } zurückkehren { Klickgriff } } } </Skript> Symbolschriftart abrufen www.flaticon.com/ ZusammenfassenDies ist das Ende dieses Artikels über die Verwendung von vue3 zum Imitieren des Nebennachrichten-Eingabeaufforderungseffekts des Apple-Systems. Weitere relevante Inhalte zum Imitieren von Apples Nebennachrichten-Eingabeaufforderungsinhalten von vue3 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:
|
<<: Erstellen Sie mit PS in zwei Minuten eine Homepage für eine XHTML+CSS-Website
1. Nachdem Sie das Webprojekt erstellt haben, müs...
Phänomen: Nach MySQL Version 5.7 ist der Standard...
Ich hatte nichts zu tun, also kaufte ich zum Lern...
Inhaltsverzeichnis 1. Variablenübersicht 1.1 Spei...
Wir werden phpMyAdmin installieren, damit es mit ...
Kürzlich habe ich vom Vue-Projekt erfahren und bi...
Starten Sie MySQL zunächst im Skip-Grant-Tables-M...
Bei der Erstellung von Webseiten werden Eingabe un...
Inhaltsverzeichnis 1. Mittelsmann-Modell 2. Beisp...
Zusammenfassen 1. Ähnlichkeiten Beide können den ...
Mit der Array-Deduplizierung wird man häufig bei ...
Heutzutage ist die Anwendungsentwicklung grundsät...
Inhaltsverzeichnis Vorwort Konvertierungsbeziehun...
Inhaltsverzeichnis Vorwort Wie wechselt man zwisc...
Ich habe zuvor die Verwendung des asynchronen Lad...