Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VueJS slot in v-for

Tags:

vue.js

I want to make a grid component which accepts as slot additional column cell.

<grid>
  <td slot="additional-column">...</td>
</grid>

In the actual component:

<template>
   <table>
     <div v-for="item in items">
       ...
       <slot name="additional-column"></slot>
     </div>
   </table>
</template>

Unfortunately the slot starts repeating itself and this is something vuejs doesn't like.

Duplicate presence of slot "additional-column" found in the same render tree - this will likely cause render errors.

Does anybody know how can I deal with this issue?

Thanks in advance!

like image 560
Nikola Avatar asked Dec 08 '17 16:12

Nikola


People also ask

What is slot used for in Vue?

Slot props allow us to turn slots into reusable templates that can render different content based on input props. This is most useful when you are designing a reusable component that encapsulates data logic while allowing the consuming parent component to customize part of its layout.

What is the V-slot?

v-slot is used on an HTML element. v-slot can only be used on a <template> element or the component receiving the slot. Otherwise, Vue throws a compile error. See Example 1 below. v-slot is used on a component, but the component has another <template v-slot> as a child.

How do you use Vue component slots?

There are two steps to using named slots in Vue: Naming our slots from our child component using the name attribute. Providing content to these named slots from our parent component using the v-slot directive.

How do you make your own slots at Vue?

You add a colon ( : ) after v-slot and then write the name of the slot you want the content to be passed to. Note that v-slot is new to Vue 2.6, so if you're using an older version, you'll need to read the docs about the deprecated slot syntax.


1 Answers

Make the item a nested component (which you'll be repeating using v-for) and render the additional-column slot in that particular component.

That's the proper way to overcome this issue. The idea is that you need to have one single slot with a particular name per component.

That is, you could do it that way, which is a very rough version of it but nicely outlines the idea:

<!-- Grid Template -->
<template>
  <table>
    <GridItem :item="item" v-for="item in items">
      <!-- Maybe even pass that column conditionally, based on the item data -->
      <div slot="additional-column">
        Content of column
      </div>
    </GridItem>
  </table>
</template>


<!-- GridItem Template -->
<template>
  <div>
    <div>Column 1</div>
    <div>Column 2</div>
    <slot name="additional-column" />
  </div>
</template>
like image 168
Andrei Glingeanu Avatar answered Sep 21 '22 18:09

Andrei Glingeanu