I\'m trying to create a reusable component for iterating over items, filtering them, and adding some classes to the slot (if the item is even, odd, first, last etc..)
<I have another way can get your aim, but not use render
, still use slot
.
The reusable component:
<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>
use _class
to class
keyword, so Vue.js
will let _class
as the common property.
Then in your use:
<component-list :classes="'some-class'" :items="category.products">
<template scope="{ item, _class }">
<product :product="item" :class="_class"></product>
</template>
<component-list>
By the scope property, your can still get _class
from slot.
After all, use render
may be more conciseness. :)
With vuejs2
styling from slots has been removed as stated here:
Content inserted via named no longer preserves the slot attribute. Use a wrapper element to style them, or for advanced use cases, modify the inserted content programmatically using render functions.
So simplest thing as suggested will be to use a wrapper element as following:
<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>
In your child component don't use the slot tag, just bind the slot data to a normal element.
For example say I have a component called modal. In my parent I have this:
<modal>
<h1 slot="title">My modal title</h1>
</modal>
So with normal slot use my child component would have the following markup:
<slot name="title" class="this-class-will-not-get-added"></slot>
But that class will not get added.
So instead we can do this:
<h1 class="this-class-will-get-added">{{this.$slots.title['0'].children['0'].text}}</h1>