2014-05-22 14 views
7

Wann sollte ich eine Anweisung im Vergleich zu einer Komponente in vue.js verwenden? Ich implementiere einige Sachen von Bootstrap und es sieht so aus, als könnte ich es auf jede Art machen (ich fange mit dem Dropdown-Menü an).Anwendungsfälle für vue.js-Richtlinie vs Komponente?

Ich habe das Gefühl, dass eine Direktive mehr für die Manipulation der Dom auf einem einzelnen Element ist, während Komponenten für die Verpackung einer Reihe von Daten und/oder dom Manipulation sind. Ist das ein guter Weg, um es zu betrachten?

Antwort

11

Diese Stapelüberlauf-Frage ist das erste Ergebnis der Google-Abfrage "vue directive vs component". Saurshaz 'Antwort ist derzeit die akzeptierte und in Vue 2.0 ist es sehr falsch. Ich kann mir vorstellen, dass dies viele Leute in die Irre führt, also werde ich hier abwiegen.

Die Antwort auf "sollte ich eine Richtlinie oder eine Komponente in Vue verwenden" ist fast immer eine Komponente.

Möchten Sie wiederverwendbares HTML verwenden? I.e. wiederverwendbare Widgets? Dann benutze eine Komponente. Möchten Sie, dass zwei dieser Widgets diskrete Daten haben? Dann benutze eine Komponente. Die Daten von einem werden NICHT überschreiben die Daten eines anderen. Vielleicht war das in Vue 1.0 richtig, ich weiß es nicht. Aber das ist in Vue 2.0 absolut nicht richtig. In Vue 2.0 verfügen Ihre Komponenten über eine data-Funktion, die einen eindeutigen Datensatz zurückgibt. Betrachten Sie diese wirklichen Leben eines Vue Drop-Down, die eine HTML-Markup ähnlich dem UI Bootstrap Dropdown hat:

<template> 
    <span class="dropdown sm-dropdown" @click="toggle" :class="{'open': isOpen}"> 
    <a class="dropdown-toggle"> 
     <span class="special-field">{{ label }}</span> 
    </a> 
    <ul class="dropdown-menu"> 
     <li v-for="choice in choices"> 
     <a @click.prevent="click(choice)">{{ choice.label }}</a> 
     </li> 
    </ul> 
    </span> 
</template> 

<script> 
    export default { 
    name: 'Dropdown', 
    props: ['label', 'options', 'onChange'], 
    data() { 
     return { 
     choices: this.options, 
     isOpen: false 
     } 
    }, 
    methods: { 
     click(option) { 
     this.onChange(option); 
     }, 
     toggle() { 
     this.isOpen = !this.isOpen; 
     } 
    } 
    } 
</script> 

nun in einer übergeordneten Komponente, kann ich so etwas tun:

<template>  
    <div class="container"> 
    <dropdown 
     :label="-- Select --" 
     :options="ratingChoices" 
     :onChange="toggleChoice" 
    > 
    </dropdown> 

    <dropdown 
     :label="-- Select --" 
     :options="ratingChoices" 
     :onChange="toggleChoice" 
    > 
    </dropdown> 
    </div> 
</template> 

<script> 
    import Dropdown from '../dropdown/dropdown.component.vue'; 

    export default { 
    name: 'main-directive', 
    components: { Dropdown }, 
    methods: { 
     toggleChoice(newChoice) { 
     // Save this state to a store, e.g. Vuex 
     } 
    }, 
    computed: { 
     ratingChoices() { 
     return [{ 
      value: true, 
      label: 'Yes' 
     }, { 
      value: false, 
      label: 'No' 
     }] 
     } 
    } 
    } 
</script> 

Es gibt eine Anständige Menge an Code hier. Was passiert, ist, dass wir eine Elternkomponente einrichten und innerhalb dieser Elternkomponente zwei Dropdown-Listen haben. Mit anderen Worten, die Dropdown-Komponente wird zweimal aufgerufen. Der Punkt, den ich versuche, diesen Code anzuzeigen, ist folgender: Wenn Sie auf das Dropdown klicken, ändert sich die isOpen für diese dropdown nur für diese Richtlinie und für diese Richtlinie. Wenn Sie auf eines der Dropdown-Menüs klicken, wirkt sich dies nicht auf das andere Dropdown-Menü aus.

Wählen Sie nicht zwischen Komponenten oder Direktiven basierend darauf, ob Sie diskrete Daten wünschen oder nicht. Komponenten ermöglichen diskrete Daten.

Also wann möchten Sie eine Richtlinie in Vue wählen?

Hier sind ein paar Richtlinien, die Sie hoffentlich in die richtige Richtung denken lassen.

  • Sie mögen eine Richtlinie wählen, wenn Sie wollen, um die Funktionalität von HTML-Komponenten zu erweitern und Sie vermuten, dass Sie diese extendability über mehrere Komponenten benötigen gehen und Sie wollen nicht Ihren DOM tiefer zu bekommen als Ergebnis. Um zu verstehen, was ich damit meine, schauen wir uns die Anweisungen an, die Vue sofort bereitstellt. Nehmen Sie zum Beispiel die v-for Richtlinie. Es ermöglicht Ihnen, eine Sammlung zu durchlaufen. Das ist sehr nützlich und Sie müssen in der Lage sein, dies in jeder beliebigen Komponente zu tun, und Sie möchten nicht, dass das DOM tiefer geht. Das ist ein gutes Beispiel dafür, wann eine Richtlinie die bessere Wahl ist. [1]
  • Sie möchten eine Anweisung auswählen, wenn ein einzelnes HTML-Tag mehrere-Funktionen haben soll. Beispielsweise ein Element, das sowohl eine Ajax-Anforderung auslöst als auch eine benutzerdefinierte QuickInfo enthält. Angenommen, Sie möchten Tooltips auf anderen Elementen als Ajax-auslösenden Elementen haben, ist es sinnvoll, diese in zwei verschiedene Dinge aufzuteilen. In diesem Beispiel würde ich den Tooltip zu einer Direktive machen und das Ajax-Feature durch eine Komponente steuern, so dass ich die eingebaute @click Direktive nutzen könnte, die in Komponenten verfügbar ist.

Eine Fußnote für die Neugierigen. In der Theorie v-for könnte als eine Komponente gemacht worden sein, aber dies getan hätte erfordern ein tiefer als notwendig DOM jedes Mal, wenn Sie v-for sowie eine peinliche Syntax verwenden wollten. Wenn hatte Vue gewählt, um eine Komponente aus ihm zu machen, statt dies:

<a v-for="link in links" :href="link.href">link.anchor</a> 

Die Syntax hätte dazu gewesen:

<v-for items="link in links"> 
    <a :href="link.href">link.anchor</a> 
</v-for> 

Nicht nur diese ungeschickt ist, aber da die Komponente Code hätte benötigt, um die <slot></slot> Syntax zu implementieren, um die innereHTML zu bekommen, und da Slots nicht unmittelbare Kinder einer <template> Deklaration sein können (da es keine Garantie gibt, dass Slot Markup einen einzigen Knoten des Eintrags auf seiner obersten Ebene hat), bedeutet dies dort müsste ein umgebendes Element der obersten Ebene in der Komponentendefinition fürsein. Daher würde das DOM tiefer als nötig werden. Die Richtlinie war hier eindeutig die richtige Wahl.

0

Reusability ist ein Grund für die Verwendung Richtlinien

Während Komponenten werden auch wiederverwendbar ‚Widgets‘, zwei Komponenten in der gleichen HTML-System zu schaffen würden die vorherigen ‚Daten‘ überschreiben, so denken von Richtlinien in einem solchen Fall Dies.

Ein weiterer Punkt, an den es sich zu denken lohnt, ist - Kann der Benutzer es über HTML nur nach einigen Anweisungen verwenden?

3

Ich denke, es auf diese Art und Weise:

Komponenten Widgets definieren - das sind Abschnitte von HTML, das Verhalten mit ihnen verbunden haben.

Direktiven modifizieren Verhalten von Abschnitten von HTML (die Widgets sein können oder nicht).

Verwandte Themen