Skip to content Skip to sidebar Skip to footer

Bind Class To A Slot In Vue.js 2

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..) Here's my reus

Solution 1:

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>

Solution 2:

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. :)


Solution 3:

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>

Post a Comment for "Bind Class To A Slot In Vue.js 2"