Heim >Web-Frontend >js-Tutorial >Vue Composables-Tipps, die Sie wissen müssen
Vue Composables sind unglaublich leistungsstark, können aber schnell unordentlich und schwer zu warten werden, wenn Sie nicht aufpassen.
Deshalb habe ich 13 Tipps identifiziert, die Ihnen dabei helfen, bessere und wartbarere Composables zu schreiben.
Ob Sie eine einfache Zustandsverwaltungslösung oder komplexe gemeinsame Logik erstellen, diese Tipps werden Ihnen helfen:
Die Tipps, die Sie lernen werden, sind:
Lassen Sie uns in jedes Muster eintauchen und sehen, wie sie Ihre Vue-Anwendungen verbessern können.
Und vergessen Sie nicht, unten Ihren Lieblingstipp zu kommentieren!
Das Datenspeichermuster kann dabei helfen, die Weitergabe von Requisiten und Ereignissen über mehrere Komponentenebenen zu vermeiden.
Eine Situation ist, dass Eltern und Kind durch endloses Bohren von Requisiten und das Sprudeln von Ereignissen miteinander kommunizieren:
<!-- Parent.vue --> <template> <!-- But many more layers of components --> <Child :user="user" @change="onUserChange" /> </template> <script setup> const user = ref({ name: 'Alice' }) function onUserChange(updatedUser) { user.value = updatedUser } </script>
Dies führt zu großer Komplexität, da sich diese Requisiten und Ereignisse in der Komponentenhierarchie hin und her bewegen müssen.
Eine einfachere Lösung besteht darin, einen gemeinsamen Datenspeicher zu erstellen, den jede Komponente importieren kann:
import { reactive, toRefs } from 'vue' const state = reactive({ user: { name: 'Alice' } }) export function useUserStore() { return toRefs(state) }
Das Data Store Pattern hilft auch, wenn Geschwister- oder „Cousin“-Komponenten dieselben Daten ohne direkte Verbindung teilen müssen.
Angenommen, zwei Geschwister benötigen beide dasselbe Benutzerobjekt, aber es gibt keinen eleganten Pfad für Requisiten oder Ereignisse.
Dies führt häufig zu einer umständlichen Datenverarbeitung durch einen übergeordneten oder duplizierten Status.
Ein besserer Ansatz besteht darin, sich auf einen einzigen zusammensetzbaren Shop zu verlassen, den beide Geschwister nutzen können:
// SiblingA.vue import { useUserStore } from './useUserStore' const { user } = useUserStore() // SiblingB.vue import { useUserStore } from './useUserStore' const { user } = useUserStore()
Das Data Store Pattern empfiehlt die Bereitstellung klarer Methoden zum Aktualisieren des freigegebenen Status.
Einige Entwickler machen das gesamte reaktive Objekt der Welt zugänglich, etwa so:
<!-- Parent.vue --> <template> <!-- But many more layers of components --> <Child :user="user" @change="onUserChange" /> </template> <script setup> const user = ref({ name: 'Alice' }) function onUserChange(updatedUser) { user.value = updatedUser } </script>
Damit kann jeder die DarkMode-Eigenschaft des Benutzers direkt aus jeder Datei ändern, was zu vereinzelten, unkontrollierten Mutationen führen kann.
Eine bessere Idee besteht darin, den Status als schreibgeschützt zurückzugeben, zusammen mit Funktionen, die definieren, wie Aktualisierungen erfolgen:
import { reactive, toRefs } from 'vue' const state = reactive({ user: { name: 'Alice' } }) export function useUserStore() { return toRefs(state) }
Das Inline Composables Pattern hilft dabei, große Komponenten aufzuteilen, indem es zusammengehörige Zustände und Logik in kleineren Funktionen zusammenfasst.
Eine riesige Komponente könnte alle ihre Referenzen und Methoden an einem Ort unterbringen:
// SiblingA.vue import { useUserStore } from './useUserStore' const { user } = useUserStore() // SiblingB.vue import { useUserStore } from './useUserStore' const { user } = useUserStore()
Dieses Setup wird schnell unüberschaubar.
Stattdessen kann ein Inline-Composable die Logik gruppieren und lokal bereitstellen. Wir können es dann später in eine separate Datei extrahieren:
export const user = reactive({ darkMode: false })
Das Thin Composables Pattern weist uns an, die reine Geschäftslogik von der Vue-Reaktivität zu trennen, damit Tests und Wartung einfacher werden.
Sie können die gesamte Logik in das Composable einbetten:
import { reactive, readonly } from 'vue' const state = reactive({ darkMode: false }) export function toggleDarkMode() { state.darkMode = !state.darkMode } export function useUserStore() { return { darkMode: readonly(state.darkMode), toggleDarkMode } }
Das zwingt Sie dazu, die Logik in einer Vue-Umgebung zu testen.
Behalten Sie stattdessen die komplizierten Regeln in reinen Funktionen und lassen Sie das Composable nur reaktive Wrapper verarbeiten:
<script setup> const count = ref(0) const user = ref({ name: 'Alice' }) // 500 more lines of intertwined code with watchers, methods, etc. </script>
Das Async Sync Composables Pattern führt sowohl synchrone als auch asynchrone Verhaltensweisen zu einem Composable zusammen, anstatt separate Funktionen zu erstellen.
Genauso funktioniert Nuxts useAsyncData.
Hier haben wir ein einzelnes Composable, das ein Versprechen zurückgeben und gleichzeitig sofort reaktive Eigenschaften für die synchrone Verwendung bereitstellen kann:
<script setup> function useCounter() { const count = ref(0) const increment = () => count.value++ return { count, increment } } const { count, increment } = useCounter() </script>
Das Optionsobjektmuster kann lange Parameterlisten löschen, indem es ein einzelnes Konfigurationsobjekt erwartet.
Aufrufe wie dieser sind umständlich und fehleranfällig, und das Hinzufügen neuer Optionen erfordert eine Aktualisierung der Funktionssignatur:
export function useCounter() { const count = ref(0) function increment() { count.value = (count.value * 3) / 2 } return { count, increment } }
Es ist nicht offensichtlich, wofür jedes Argument steht.
Ein Composable, das ein Optionsobjekt akzeptiert, sorgt dafür, dass alles beschreibend bleibt:
// counterLogic.js export function incrementCount(num) { return (num * 3) / 2 } // useCounter.js import { ref } from 'vue' import { incrementCount } from './counterLogic' export function useCounter() { const count = ref(0) function increment() { count.value = incrementCount(count.value) } return { count, increment } }
Das Optionsobjektmuster empfiehlt außerdem Standardwerte für jede Eigenschaft.
Eine Funktion, die davon ausgeht, dass bestimmte Felder vorhanden sind, kann problematisch sein, wenn sie nicht übergeben werden:
import { ref } from 'vue' export function useAsyncOrSync() { const data = ref(null) const promise = fetch('/api') .then(res => res.json()) .then(json => { data.value = json return { data } }) return Object.assign(promise, { data }) }
Es ist besser, Optionen mit sicheren Standardeinstellungen zu zerstören:
useRefHistory(someRef, true, 10, 500, 'click', false)
Das dynamische Rückgabemuster stellt sicher, dass ein Composable entweder einen einzelnen Wert für einfache Anwendungsfälle oder ein erweitertes Objekt mit erweiterten Steuerelementen zurückgeben kann.
Einige Ansätze geben immer ein Objekt mit allem zurück:
<!-- Parent.vue --> <template> <!-- But many more layers of components --> <Child :user="user" @change="onUserChange" /> </template> <script setup> const user = ref({ name: 'Alice' }) function onUserChange(updatedUser) { user.value = updatedUser } </script>
Wer nur den Hauptreaktivwert benötigt, ist gezwungen, sich mit zusätzlichen Dingen auseinanderzusetzen.
Ein Composable, das bedingt eine einzelne Referenz oder ein Objekt zurückgibt, löst Folgendes:
import { reactive, toRefs } from 'vue' const state = reactive({ user: { name: 'Alice' } }) export function useUserStore() { return toRefs(state) }
Das Hidden Composables Pattern trägt dazu bei, die Vermischung sich gegenseitig ausschließender Logik im selben Composable zu vermeiden.
Einiger Code fasst mehrere Modi oder Codepfade zusammen:
// SiblingA.vue import { useUserStore } from './useUserStore' const { user } = useUserStore() // SiblingB.vue import { useUserStore } from './useUserStore' const { user } = useUserStore()
Das Aufteilen jedes Pfads in seine eigenen zusammensetzbaren Pfade ist viel klarer und hat keinen Einfluss auf die Funktionalität:
export const user = reactive({ darkMode: false })
Das Flexible Arguments Pattern stellt sicher, dass Eingaben und Ausgaben in Composables einheitlich als reaktive Daten oder Rohwerte behandelt werden, wodurch Verwirrung vermieden wird.
Einige Codes prüfen, ob eine Eingabe eine Referenz ist oder nicht:
import { reactive, readonly } from 'vue' const state = reactive({ darkMode: false }) export function toggleDarkMode() { state.darkMode = !state.darkMode } export function useUserStore() { return { darkMode: readonly(state.darkMode), toggleDarkMode } }
Stattdessen können Sie sofort konvertieren.
Wenn bei Verwendung von ref die Eingabe eine Referenz ist, wird diese Referenz zurückgegeben. Andernfalls wird es in eine Referenz umgewandelt:
<script setup> const count = ref(0) const user = ref({ name: 'Alice' }) // 500 more lines of intertwined code with watchers, methods, etc. </script>
Das Muster für flexible Argumente verwendet auch toValue, wenn ein Auspacken erforderlich ist.
Ohne es führt der Code möglicherweise weiterhin isRef-Prüfungen durch:
<script setup> function useCounter() { const count = ref(0) const increment = () => count.value++ return { count, increment } } const { count, increment } = useCounter() </script>
Es ist viel einfacher anzurufen:
export function useCounter() { const count = ref(0) function increment() { count.value = (count.value * 3) / 2 } return { count, increment } }
Mit dem Options-to-Composition-Muster können Sie große Options-API-Komponenten Schritt für Schritt auf eine inkrementelle Weise, die einfach zu befolgen ist, in die Composition-API migrieren.
Eine klassische Optionskomponente könnte Folgendes tun:
// counterLogic.js export function incrementCount(num) { return (num * 3) / 2 } // useCounter.js import { ref } from 'vue' import { incrementCount } from './counterLogic' export function useCounter() { const count = ref(0) function increment() { count.value = incrementCount(count.value) } return { count, increment } }
Daten, berechnete Eigenschaften und Methoden sind verstreut.
Durch die Konvertierung in ein Skript-Setup werden sie zusammengeführt, es wird einfacher, ihnen zu folgen, und Sie können die folgenden Muster verwenden:
import { ref } from 'vue' export function useAsyncOrSync() { const data = ref(null) const promise = fetch('/api') .then(res => res.json()) .then(json => { data.value = json return { data } }) return Object.assign(promise, { data }) }
Diese 13 Tipps helfen Ihnen, bessere Vue-Composables zu schreiben, die einfacher zu warten, zu testen und in Ihren Anwendungen wiederzuverwenden sind.
Aber wir kratzen hier nur an der Oberfläche.
Im Laufe der Jahre habe ich viele weitere Muster und Tipps gesammelt und sie alle in einem ausführlichen Kurs über zusammensetzbare Muster zusammengefasst.
Es deckt insgesamt 16 Muster ab und jedes Muster hat:
Hier erfahren Sie mehr.
Oh, und dieser Kurs ist bis zum 15. Januar im Angebot, sodass Sie ihn jetzt mit einem tollen Rabatt erhalten können!
Schauen Sie sich Composable Design Patterns an
Das obige ist der detaillierte Inhalt vonVue Composables-Tipps, die Sie wissen müssen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!