Mit Scoped-Ablagefächer in Vue.js zu Abstrakte Funktionalität

0
24

Beginnen wir mit einer kurzen Einführung in die Vue.js slots-Konzept. Slots sind nützlich, wenn Sie möchten, um zu injizieren, Inhalte in einem bestimmten Ort einer Komponente. Diese spezifischen Orte, die Sie definieren, werden slots genannt.

Zum Beispiel, Sie möchten, erstellen Sie eine wrapper-Komponente Stil in einer bestimmten Weise, aber Sie wollen in der Lage sein, um pass-Inhalte wiedergegeben werden innen die wrapper – (es kann ein string sein, der einen berechneten Wert, oder auch eine andere Komponente).

Es gibt drei Arten von Spielautomaten:

  • Standard / Unbenannt-Steckplätze: verwendet, wenn Sie eine single-slot-in einer Komponente. Wir erstellen Sie durch hinzufügen <slot> in der Vorlage, wo wir sein wollen in der Lage zu injizieren unsere Inhalte. Diese <slot> – tag ersetzt werden, jeder Inhalt der übergeben der Komponente der Vorlage.
  • benannte slots: verwendet, wenn Sie mehrere Spielautomaten in einer Komponente, und wir wollen zu injizieren verschiedene Inhalte an verschiedenen Orten (slots). Wir erstellen diese durch hinzufügen <slot> mit einem name-Attribut (z.B. <slot name=”header”></slot>). Wenn dann machen wir unsere Komponenten bieten wir eine slot-Inhalte für jeden namens-Schlitz, indem ein slot-Attribut mit dem slot-Namen.

<Basis-layout”>
<Vorlage-slot=”header”>
<h1>Meine awsome header</h1>
</template>
<Vorlage-slot=”footer”>
<p>Meine awsome Fußzeile</p>
</template>
</base-layout”>

Dadurch, dass die <slot> – tags in die Komponente wird ersetzt durch den Inhalt, der an die Komponente.

  • Gültigkeitsbereich slot: verwendet, wenn Sie eine Vorlage innerhalb einer slot-Zugriff auf Daten aus der Kind-Komponente, die macht der slot-Inhalt. Dies ist besonders nützlich, wenn Sie brauchen Freiheit bei der Erstellung von benutzerdefinierten Vorlagen, die mit der Kinder-Komponente Daten-Eigenschaften.

Real-World Beispiel: Erstellen einer Google Map Loader-Komponente

Stellen Sie sich eine Komponente, die konfiguriert und bereitet eine externe API verwendet werden, die in einer anderen Komponente, aber nicht eng gekoppelt mit einer bestimmten Vorlage. Eine solche Komponente könnte dann wiederverwendet werden in mehreren Orten zwischen verschiedenen Vorlagen, sondern mit den gleichen Basis-Objekt mit einer bestimmten API.

Ich habe eine Komponente (GoogleMapLoader.vue):

  1. initialisiert die Google Maps API
  2. erstellt google und map-Objekte
  3. stellt die Objekte für die übergeordnete Komponente, in der das GoogleMapLoader verwendet wird

Unten ist ein Beispiel, wie dies erreicht werden kann. Wir analysieren den code Stück für Stück und sehen, was tatsächlich geschieht im nächsten Abschnitt.

Lassen Sie uns zunächst unsere GoogleMapLoader.vue Vorlage:

<Vorlage>
<div>
<div class=”google-Karte” Daten-google-map></div>
<Vorlage v-if=”Boolean(dies.google) && Boolean(dies.anzeigen)”>
<slot :google=”google” :map ” =”Karte” />
</template>
</div>
</template>

Nun, unser Skript benötigt einige Requisiten um die Komponente, die es ermöglicht, uns um die Google Maps API und Map-Objekt:

import GoogleMapsApiLoader von “google-maps-api-loader”;

export default {
Requisiten: {
mapConfig: Objekt,
apiKey: String
},
Daten() {
return {
google: null,
Karte: null
};
},
async gemountet() {
const googleMapApi = erwarten GoogleMapsApiLoader({
apiKey: dies.apiKey
});
diese.google = googleMapApi;
diese.initializeMap();
},
Methoden: {
initializeMap() {
const mapContainer = this.$el.querySelector(“[data-google-map]”);
diese.map = new diese.google.maps.Karte(mapContainer, diese.mapConfig);
}
}
};

Dies ist nur ein Teil von einem Beispiel arbeiten. Tauchen Sie noch tiefer ein in diesem Beispiel.

OK, jetzt haben wir unseren use-case-set-up, lassen Sie uns bewegen auf zu brechen, der code unten, um zu erkunden, was es tut.

1. Erstellen Sie eine Komponente, die initialisiert unserer Karte

In der Vorlage, wir erstellen ein container für die Karte, die verwendet wird, montieren Sie die Map-Objekt extrahiert aus der Google Maps API.

// GoogleMapLoader.vue
<Vorlage>
<div>
<div class=”google-Karte” Daten-google-map></div>
</div>
</template>

Als Nächstes, unser Skript zu erhalten braucht Requisiten aus der übergeordneten Komponente, die es uns ermöglichen, um die Google-Karte. Diese Requisiten bestehen:

  • mapConfig: Google-Maps-config-Objekt
  • apiKey: Unsere persönlichen api-Schlüssel erforderlich, die von Google Maps

// GoogleMapLoader.vue
import GoogleMapsApiLoader von “google-maps-api-loader”;

export default {
Requisiten: {
mapConfig: Objekt,
apiKey: String
},

Dann setzen wir die Anfangswerte von google und die anzeigen auf null:

Daten() {
return {
google: null,
Karte: null
};
},

Auf den montierten Haken, wir erstellen eine Instanz googleMapApi und das map-Objekt aus. Wir müssen auch die Werte von google und anzeigen der erstellten Instanzen:

async gemountet() {
const googleMapApi = erwarten GoogleMapsApiLoader({
apiKey: dies.apiKey
});
diese.google = googleMapApi;
diese.initializeMap();
},
Methoden: {
initializeMap() {
const mapContainer = this.$el.querySelector(“[data-google-map]”);
diese.map = new diese.google.maps.Karte(mapContainer, diese.mapConfig);
}
}
};

So weit, So gut. Mit allem, was geschieht, konnten wir auch weiterhin das hinzufügen von anderen Objekten auf der Karte (Marker, Polylines, etc.) und verwenden Sie es als eine gewöhnliche map-Komponente.

Aber, wir wollen unsere GoogleMapLoader Komponente nur als loader, bereitet die Karte — wir wollen nicht etwas Rendern.

Um das zu erreichen, wir müssen es erlauben, die parent-Komponente, verwenden Sie unser GoogleMapLoader Zugriff auf diese.google und diesem.anzeigen, die sich in der GoogleMapLoader Komponente. Das ist, wo Gültigkeitsbereich slots wirklich glänzen. Scoped-slots ermöglichen es uns, setzen Sie die Eigenschaften in einem Kind-Komponente zur übergeordneten Komponente. Es klingt vielleicht wie eine Gründung, aber Bär mit mir eine minute mehr als wir Pause, weiter nach unten.

2. Erstellen Komponente, die mit unserer Initialisierung der Komponente

In der Vorlage, wir machen die GoogleMapLoader Komponente und übergeben Requisiten, die erforderlich sind, zum initialisieren der Karte.

// TravelMap.vue
<Vorlage>
<GoogleMapLoader
:mapConfig=”mapConfig”
apiKey=”yourApiKey”
/>
</template>

Unsere script-tag sollte wie folgt Aussehen:

import GoogleMapLoader von “./GoogleMapLoader”;
import { mapSettings } “@/Konstanten/mapSettings”;

export default {
components: {
GoogleMapLoader,
},
berechnet: {
mapConfig() {
return {
…mapSettings,
center: { lat: 0, lng: 0 }
};
},
}
};

Noch kein scoped-slots, also fügen wir ein.

3. Setzen google und der Zuordnung von Eigenschaften zu den übergeordneten Komponente durch hinzufügen eines scoped-slot

Schließlich, wir können hinzufügen, ein scoped-slot, die die Arbeit tun und uns ermöglichen, den Zugriff auf die untergeordnete Komponente Requisiten in der übergeordneten Komponente. Wir tun dies durch hinzufügen der <slot> – tag in der untergeordneten Komponente und die übergabe der Requisiten, die wir wollen, zu setzen (mit v-bind-Richtlinie oder :propName Kurzschrift). Es unterscheidet sich nicht von der Weitergabe der Requisiten nach unten, um die untergeordnete Komponente, sondern tun es in der <slot> – tag wird die Umkehrung der Richtung des Datenflusses.

// GoogleMapLoader.vue
<Vorlage>
<div>
<div class=”google-Karte” Daten-google-map></div>
<Vorlage v-if=”Boolean(dies.google) && Boolean(dies.anzeigen)”>
<slot
:google=”google”
:anzeigen=”anzeigen”
/>
</template>
</div>
</template>

Nun, wenn wir den slot in der Kind-Komponente, die wir brauchen, zu empfangen und zu konsumieren, die ausgesetzt Requisiten in der übergeordneten Komponente.

4. Erhalten ausgesetzt Requisiten in die übergeordnete Komponente mit der slot-scope-Attribut

Erhalten Sie die Requisiten in der übergeordneten Komponente, wir deklarieren Sie eine Vorlage-element, und verwenden Sie den Schlitz-scope-Attribut. Dieses Attribut hat den Zugriff auf das Objekt, die alle möglichen Requisiten ausgesetzt, die von der untergeordneten Komponente. Wir können, schnappen Sie sich das gesamte Objekt, oder wir können die de-Struktur, Objekt und nur das, was wir brauchen.

Lasst uns de-Struktur, dieses Ding zu bekommen, was wir brauchen.

// TravelMap.vue
<Vorlage>
<GoogleMapLoader
:mapConfig=”mapConfig”
apiKey=”yourApiKey”
>
<Vorlage-slot-scope=”{ google map }”>
{{ Karte }}
{{ google }}
</template>
</GoogleMapLoader>
</template>

Auch wenn die google-map und Requisiten nicht vorhanden sind, in der TravelMap Umfang der Komponente, die den Zugriff auf Sie hat und wir Sie in der Vorlage.

Ja, OK, aber warum sollte ich so etwas tun? Was nützt das alles?

Froh, dass Sie gefragt! Scoped-slots ermöglichen es uns, übergeben Sie eine Vorlage, um den Steckplatz anstelle eines gerenderten element. Es heißt ein scoped-slot, da Sie den Zugriff auf bestimmte Kind-Komponenten-Daten, obwohl das template gerendert wird, in der übergeordneten Komponente Bereich. Das gibt uns die Freiheit, zu füllen die Vorlage mit benutzerdefinierten Inhalte von der übergeordneten Komponente.

5. Erstellen Fabrik-Komponenten Marker und Polylines

Nun, wenn wir unsere Karte fertig, erstellen wir die zwei Werks-Komponenten, die verwendet werden, um Elemente hinzuzufügen oder Elemente der TravelMap.

// GoogleMapMarker.vue
import { POINT_MARKER_ICON_CONFIG } “@/Konstanten/mapSettings”;

export default {
Requisiten: {
google: {
Typ: Objekt,
erforderlich: true
},
Karte: {
Typ: Objekt,
erforderlich: true
},
marker”: {
Typ: Objekt,
erforderlich: true
}
},
montiert() {
neu in diesem.google.maps.Marker({
position: dies.marker.position,
marker: dies.marker,
Karte: dies.Karte
Symbol: POINT_MARKER_ICON_CONFIG
});
},
};
// GoogleMapLine.vue
import { LINE_PATH_CONFIG } “@/Konstanten/mapSettings”;

export default {
Requisiten: {
google: {
Typ: Objekt,
erforderlich: true
},
Karte: {
Typ: Objekt,
erforderlich: true
},
Pfad: {
Typ: Array,
erforderlich: true
}
},
montiert() {
neu in diesem.google.maps.Polylinie({
Pfad: dies.Weg,
Karte: dies.Karte
…LINE_PATH_CONFIG
});
},
};

Beide erhalten von google, mit dem wir extrahieren das gewünschte Objekt (Markierung oder Polylinie) sowie eine Landkarte, die als eine Referenz auf die Karte, auf die möchten wir zu unserem element.

Jede Komponente auch erwartet, dass eine zusätzliche Stütze zum erstellen eines entsprechenden element. In diesem Fall haben wir die Markierung und den Pfad, beziehungsweise.

Auf den montierten Haken, erstellen wir ein element (Marker/Polylinie), und befestigen Sie es auf unserer Karte durch die übergabe der anzeigen-Eigenschaft auf das Objekt-Konstruktor.

Es gibt noch einen weiteren Schritt zu gehen…

6. Hinzufügen von Elementen auf der Karte anzeigen

Wir verwenden unsere Fabrik-Komponenten hinzufügen Elemente unserer Karte. Wir müssen machen die factory-Komponente und übergeben Sie die google-und map-Objekten, so dass Daten-Ströme an die richtigen stellen.

Wir brauchen auch die Angaben, die erforderlich ist, um das element selbst. In unserem Fall, das ist das marker-Objekt mit der position des markers und die Pfad-Objekt mit Polyline-Koordinaten.

Hier gehen wir, die Integration der Daten, die Punkte direkt in das template:

// TravelMap.vue
<Vorlage>
<GoogleMapLoader
:mapConfig=”mapConfig”
apiKey=”yourApiKey”
>
<Vorlage-slot-scope=”{ google map }”>
<GoogleMapMarker
v-=” – marker im Marker”
:key=”marker.id”
:marker=”markiert”
:google=”google”
:anzeigen=”anzeigen”
/>
<GoogleMapLine
v-=” – Zeile in den Zeilen”
:key=”Zeile.id”
:Weg.sync=”Zeile.Pfad”
:google=”google”
:anzeigen=”anzeigen”
/>
</template>
</GoogleMapLoader>
</template>

Wir müssen importieren Sie die erforderlichen Fabrik-Komponenten in unserem Skript und setzen Sie die Daten, die übergeben werden, um die Markierungen und Linien:

import { mapSettings } “@/Konstanten/mapSettings”;

export default {
components: {
GoogleMapLoader,
GoogleMapMarker,
GoogleMapLine
},
Daten() {
return {
Marker: [
{ id: “a”, position: { lat: 3, lng: 101 } },
{ id: “b”, position: { lat: 5, lng: 99 } },
{ id: “c”, position: { lat: 6, lng: 97 } }
],
Linien: [
{ id: “1”, Pfad: [{ lat: 3, lng: 101 }, { lat: 5, lng: 99 }] },
{ id: “2”, Pfad: [{ lat: 5, lng: 99 }, { lat: 6, lng: 97 }] }
]
};
},
berechnet: {
mapConfig() {
return {
…mapSettings,
center: dies.mapCenter
};
},
mapCenter() {
wieder dieses.Marker[1].position;
}
}
};

Und dann sind wir fertig!

Mit all den bits und Stücke, die vollendet ist, können wir nun wieder die GoogleMapLoader Komponente als Basis für alle unsere Karten durch die Weitergabe von verschiedenen Vorlagen für jeden von Ihnen. Vorstellen, dass Sie brauchen, um zu erstellen eine weitere Karte mit verschiedenen Markierungen oder einfach nur Marker, ohne Polylinien. Mithilfe eines Musters von scoped-slots, wird es sehr einfach, da alles, was wir brauchen, um passieren nun verschiedene Inhalte zu den GoogleMapLoader Komponente.

Dieses Muster ist nicht zwingend verbunden mit Google Maps, es kann verwendet werden mit jeder Bibliothek, die Basis-Komponente und setzen die Bibliotheks-API, die könnte dann in der Komponente, der Sie beschworen die Basis-Komponente.

Es könnte verlockend sein, um eine mehr komplexe oder robuste Lösung, aber das wird uns die Abstraktion, die wir brauchen, und es wird eine unabhängige Stück unserer Codebasis. Wenn wir dahin kommen, dann wäre es vielleicht eine überlegung Wert die Beute auf ein add-on.