J'essaie de créer un composant réutilisable pour itérer sur les éléments, les filtrer et ajouter des classes à l'emplacement (si l'élément est pair, impair, premier, dernier etc.)
Voici mon composant réutilisable:
<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>
Et voici comment je l'utilise:
<component-list :classes="'some-class'" :items="category.products">
<template scope="props">
<product :product="props.item"></product>
</template>
<component-list>
Tout fonctionne comme prévu, mais cela n'ajoute pas de classes à l'élément placé à l'intérieur.
Est-ce que je fais quelque chose de mal? Est-il même techniquement possible dans Vue.js 2 de faire quelque chose comme ça?
Merci pour toute aide ou suggestion!
Avec vuejs2
, le style des emplacements a été supprimé comme indiqué ici :
Le contenu inséré via nommé ne conserve plus l'attribut slot. Utilisez un élément wrapper pour les styler ou, pour les cas d'utilisation avancés, modifiez le contenu inséré par programmation à l'aide de fonctions de rendu.
La chose la plus simple suggérée consiste à utiliser un élément wrapper comme suit:
<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>
J'ai un autre moyen d'obtenir votre objectif, mais pas d'utiliser render
, continuez d'utiliser slot
.
Le composant réutilisable:
<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>
utilise _class
à class
mot clé , donc Vue.js
laissera _class
comme propriété commune.
Alors dans votre utilisation:
<component-list :classes="'some-class'" :items="category.products">
<template scope="{ item, _class }">
<product :product="item" :class="_class"></product>
</template>
<component-list>
Par la propriété scope, vous pouvez toujours obtenir _class
à partir de la fente.
Après tout, utiliser render
peut être plus concis. :)
Dans votre composant enfant, n'utilisez pas la balise d'emplacement, mais liez simplement les données d'emplacement à un élément normal.
Par exemple, disons que j'ai un composant appelé modal. Dans mes parents, j'ai ceci:
<modal>
<h1 slot="title">My modal title</h1>
</modal>
Donc, avec une fente normale, mon composant enfant aurait le balisage suivant:
<slot name="title" class="this-class-will-not-get-added"></slot>
Mais cette classe ne sera pas ajoutée.
Au lieu de cela, nous pouvons faire ceci:
<h1 class="this-class-will-get-added">{{this.$slots.title['0'].children['0'].text}}</h1>