web-dev-qa-db-de.com

Binden Sie die Klasse an einen Slot in Vue.js. 2

Ich versuche, eine wiederverwendbare Komponente zum Durchlaufen von Elementen zu erstellen, sie zu filtern und dem Steckplatz einige Klassen hinzuzufügen (wenn das Element gerade, ungerade, zuerst, zuletzt usw. ist).

Hier ist meine wiederverwendbare Komponente:

<template>
  <ul :class="classes">
    <slot
      v-for="(item, index) in filteredItems"
      :item="item"
      :class="{
        'first': index == 0,
        'odd': !(index % 2),
        'even': index % 2,
        'last': index == (filteredItems.length - 1)
      }"
    >
    </slot>
  </ul>
</template>

<script>
export default {
  props: ['items', 'classes'],
  data() {
    return {
      filteredItems: this.items.filter(item => item.active)
    };
  }
};
</script>

Und so benutze ich es:

<component-list :classes="'some-class'" :items="category.products">
  <template scope="props">
    <product :product="props.item"></product>
  </template>
<component-list>

Alles funktioniert wie erwartet, fügt jedoch dem eingefügten Element keine Klassen hinzu.

Mache ich etwas falsch? Ist es in Vue.js 2 sogar technisch möglich, so etwas zu tun?

Danke für jede Hilfe oder Anregung!

8

Mit vuejs2 wurde das Styling aus den Slots entfernt hier

Über named eingefügter Inhalt behält das Slot-Attribut nicht mehr bei. Verwenden Sie ein Wrapper-Element, um sie zu formatieren, oder ändern Sie den eingefügten Inhalt für erweiterte Anwendungsfälle programmgesteuert mit Renderfunktionen.

So einfach wie vorgeschlagen wird es sein, ein Wrapper-Element wie folgt zu verwenden:

<template>
  <ul :class="classes">
    <slot>
      <div
      v-for="(item, index) in filteredItems"
      :item="item"
      :class="{
        'first': index == 0,
        'odd': !(index % 2),
        'even': index % 2,
        'last': index == (filteredItems.length - 1)
      }"
    >
    </div>
    </slot>
  </ul>
</template>
7
Saurabh

Ich habe einen anderen Weg, um Ihr Ziel zu erreichen, aber render nicht verwenden, dennoch slot verwenden.

Die wiederverwendbare Komponente:

<template>
  <ul :class="classes">
    <slot
      v-for="(item, index) in filteredItems"
      :item="item"
      :_class="{
        'first': index == 0,
        'odd': !(index % 2),
        'even': index % 2,
        'last': index == (filteredItems.length - 1)
      }"
    >
    </slot>
  </ul>
</template>

<script>
export default {
  props: ['items', 'classes'],
  data() {
    return {
      filteredItems: this.items.filter(item => item.active)
    };
  }
};
</script>

_class für class Schlüsselwort verwenden, damit Vue.js_class als allgemeine Eigenschaft verwendet.

Dann in Ihrer Verwendung:

<component-list :classes="'some-class'" :items="category.products">
  <template scope="{ item, _class }">
    <product :product="item" :class="_class"></product>
  </template>
<component-list>

Durch die scope-Eigenschaft können Sie noch _class vom Slot erhalten.

Verwenden Sie render immer noch präziser. :)

1
TomIsion

Verwenden Sie in Ihrer untergeordneten Komponente das Slot-Tag nicht, sondern binden Sie die Slot-Daten einfach an ein normales Element.

Angenommen, ich habe eine Komponente namens Modal. Bei meinen Eltern habe ich folgendes:

<modal>
    <h1 slot="title">My modal title</h1>
</modal>

Bei normaler Steckplatznutzung hätte meine untergeordnete Komponente die folgende Markierung:

<slot name="title" class="this-class-will-not-get-added"></slot>

Diese Klasse wird jedoch nicht hinzugefügt.

Stattdessen können wir das tun:

<h1 class="this-class-will-get-added">{{this.$slots.title['0'].children['0'].text}}</h1>
0
Felix Eve