In diesem Artikel besprechen wir, welche Probleme der Renderless-Slot-Modus in Vue lösen kann.
Die in Vue.js 2.3.0 eingeführten Scoped Slots verbessern die Wiederverwendbarkeit von Komponenten erheblich. Das Renderless-Komponentenmuster entstand, um das Problem der Bereitstellung wiederverwendbaren Verhaltens und einer steckbaren Darstellung zu lösen.
Hier werden wir sehen, wie wir das gegenteilige Problem lösen können: wie wir für ein wiederverwendbares Erscheinungsbild und ein steckbares Verhalten sorgen können.
Dieses Muster eignet sich für Komponenten, die komplexes Verhalten implementieren und über eine anpassbare Darstellung verfügen.
Es erfüllt die folgenden Funktionen:
Zum Beispiel: eine Komponente, die eine Ajax-Anfrage ausführt und das Ergebnis eines Slots anzeigt. Die Komponente verarbeitet Ajax-Anfragen und lädt den Status, während der Standard-Slot die Präsentation bereitstellt.
Dies ist eine vereinfachte Version der Implementierung:
<template> <div> <slot v-if="loading" name="loading"> <div>Loading ...</div> </slot> <slot v-else v-bind={data}> </slot> </div> </template> <script> export default { props: ["url"], data: () => ({ loading: true, data: null }), async created() { this.data = await fetch(this.url); this.loading = false; } }; </script>
Verwendung:
<lazy-loading url="https://server/api/data"> <template #default="{ data }"> <div>{{ data }}</div> </template> </lazy-loading>
Den Originalartikel zu diesem Muster finden Sie hier.
Was wäre, wenn das Problem umgekehrt wäre: Stellen Sie sich vor, das Hauptmerkmal einer Komponente wäre ihre Darstellung und außerdem sollte ihr Verhalten anpassbar sein.
Angenommen, Sie möchten eine auf SVG basierende Baumkomponente wie folgt erstellen:
Sie möchten SVG-Anzeige und -Verhalten bereitstellen, z. B. das Zurückziehen von Knoten und das Hervorheben von Text beim Klicken.
Das Problem entsteht, wenn Sie beabsichtigen, diese Verhaltensweisen nicht fest zu codieren und Benutzern der Komponente das freie Überschreiben zu ermöglichen.
Die einfache Lösung zum Aufdecken dieser Verhaltensweisen besteht darin, der Komponente Methoden und Ereignisse hinzuzufügen.
Sie könnten es so implementieren:
<script> export default { mounted() { // pseudo code nodes.on('click',(node) => this.$emit('click', node)); }, methods: { expandNode(node) { //... }, retractNode(node) { //... }, highlightText(node) { //... }, } }; </script>
Wenn der Benutzer der Komponente Verhalten zur Komponente hinzufügen möchte, muss er ref in der übergeordneten Komponente verwenden, zum Beispiel:
<template> <tree ref="tree" @click="onClick"></tree> </template> <script> export default { methods: { onClick(node) { this.$refs.tree.retractNode(node); } } }; </script>
Diese Methode hat mehrere Nachteile:
Sehen wir uns an, wie Renderless-Slots diese Probleme lösen.
Verhalten besteht im Wesentlichen darin, Reaktionen auf Ereignisse zu zeigen. Erstellen wir also einen Slot, der Zugriff auf Ereignisse und Komponentenmethoden erhält:
<template> <div> <slot name="behavior" :on="on" :actions="actions"> </slot> </div> </template> <script> export default { methods: { expandNode(node) { }, retractNode(node) { }, //... }, computed:{ actions() { const {expandNode, retractNode} = this; return {expandNode, retractNode}; }, on() { return this.$on.bind(this); } } }; </script>
Die on
-Eigenschaft ist die $on
-Methode der übergeordneten Komponente, sodass sie alle Ereignisse abhören kann . on
属性是父组件的 $on
方法,因此可以监听所有事件。
可以将行为实现为无渲染组件。接下来编写点击扩展组件:
export default { props: ['on','action'] render: () => null, created() { this.on("click", (node) => { this.actions.expandNode(node); }); } };
用法:
<tree> <template #behavior="{ on, actions }"> <expand-on-click v-bind="{ on, actions }"/> </template> </tree>
该解决方案的主要优点是:
例如,通过将图形组件声明为:
<template> <div> <slot name="behavior" :on="on" :actions="actions"> <expand-on-click v-bind="{ on, actions }"/> </slot> </div> </template>
考虑一个悬停突出显示组件:
export default { props: ['on','action'] render: () => null, created() { this.on("hover", (node) => { this.actions.highlight(node); }); } };
覆盖标准行为:
<tree> <template #behavior="{ on, actions }"> <highlight-on-hover v-bind="{ on, actions }"/> </template> </tree>
添加两个预定义的行为:
<tree> <template #behavior="{ on, actions }"> <expand-on-click v-bind="{ on, actions }"/> <highlight-on-hover v-bind="{ on, actions }"/> </template> </tree>
作为行为的组件是能够自描述的。
on
rrreee
Die Hauptvorteile dieser Lösung sind: Zum Beispiel durch Einfügen des Grafik Eine Komponente, deklariert als:rrreeeÜberschreiben Sie die Standardverhalten:
Sie können eine wiederverwendbare Komponente erstellen und Standardverhalten implementieren, die Benutzer, die diese Komponente verwenden, auswählen können
Betrachten Sie eine Hover-Highlight-Komponente:
rrreee
rrreeeFügen Sie zwei vordefinierte Verhaltensweisen hinzu:
Verhaltensslots sind zusammensetzbar
rrreee
Da sich die Komponenten des Verhaltens selbst beschreiben. Dason
-Attribut bietet Zugriff auf alle Komponentenereignisse. Für diesen Slot sind standardmäßig neue Events verfügbar.
ZusammenfassungRenderless-Slots bieten eine interessante Lösung zum Offenlegen von Methoden und Ereignissen in Komponenten. Sie bieten besser lesbaren und wiederverwendbaren Code.
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Nicht-Rendering-Verhaltensslots in Vue. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!