Vue: <slot :name="xxx"></slot> :slot="xxx" not worked in v-for loop

Created on 18 Mar 2016  ·  10Comments  ·  Source: vuejs/vue

In my code, a component is registered with different slot names calculated in a v-for loop as below:

//template
<script type="text/x-vue-template" id="slot-parent-template">
    <ul>
        <li v-for="item in items">
            <h1>{{item}}</h1>
            //slot name is computed by item (data type Number)
            <slot :name="item"></slot>
        </li>
    </ul>
</script>
//register component and init instance in js
<script type="text/javascript">
    Vue.component('slot-parent',{
        props:['items'],
        template:"#slot-parent-template"
    });
    new Vue({
        el:'body',
        data:{
            items:[1,2,3,4,5]
        }
    });
</script>

and below code works fine :

//in html
<slot-parent :items="items">
    //insert every slot manually works fine
    <p slot="1">1</p>
    <p slot="2">2</p>
    <p slot="3">3</p> 
    <p slot="4">4</p>
    <p slot="5">5</p>
</slot-parent>

but when I changed the code as below, slot can't be inserted into the component view,

//in html
<slot-parent :items="items">
   // insert slots with v-for loop, slot names are calculated by item
    <p v-for="item in items" :slot="item">{{item}}</p>
</slot-parent>

is the way I design this component wired ? or still there is any other way to solve the problem ?
I understand partial and component can be used in the slot-parent to do the same thing, but how about just do this with slot, since slot content can be written obviously in html file.

By the way, same problem found in Vue forum
http://forum.vuejs.org/topic/3448/dynamic-slot-names-not-working-anymore-in-new-version/5

wontfix

Most helpful comment

This has been fixed in 1.0.18.

All 10 comments

This has been fixed in 1.0.18.

Thanks for the reply.
I tested below code in 1.0.18, not work yet.
I will send you a live demo link later since typing on mobile makes me crazy.

//in html
<slot-parent :items="items">
   // insert slots with v-for loop, slot names are calculated by item
    <p v-for="item in items" :slot="item">{{item}}</p>
</slot-parent>

@yyx990803 Its certainly reproducing:
https://jsfiddle.net/fhfcz8rd/1/

@fullfs Thanks for your reproducing! I dont't have to do it again.

So, after some more investigation, I don't think we will be implementing this. This means slot attributes must be static and we will be adding a warning for it. (but names can be dynamic)

The reason is a bit complicated: consider <slot>s inside a conditional v-if block, or inside v-for, they may be destroyed and re-created again. This means they have to compile-on-demand to ensure correct lifecycle hooks being called on components inserted into slots - thus we cannot pre-compile the inserted content and simply distribute them later.

Another consideration is that a rendered v-for list needs to move the DOM nodes when the data changes - if they are moved into other places, v-for cannot ensure the correct behavior.

This does rule out the use case you demonstrated; however there will be other ways to achieve the same end result. You will probably have to rely on partials/components for now. But we will see if we can come up with something that allows you to have the markup right in the template.

Hello Evan!

I'm also affected by this. How do you think I should build the following (simplified) component:

  • Generic component called composite
  • It has a prop named elementswith an array of the logic ids (i.e. ['element1', 'element2'])
  • The component iterate over the elementsand inject the slotsby name

I made a fiddle with an example of how I would like to use the component, and it's working only if the slots are injected without a v-for
https://jsfiddle.net/anxolin/5rzmsyoq/

Is there a way to achieve this?

Thanks in advance!

Damn, I would like to make a TableLayout component that takes the number of rows and columns as props, creates a grid, and then being able to slot in components that get placed in the right cells based on row and column value props.

Not sure how to do this now.

@Volcanic-Penguin Don't know about your use case but you can check out https://stackoverflow.com/a/47073489/3301436

This have worked for me in my use case
May not be ideal solution but working none the less!

v2.5.18 可以了 slot可以在v-for 下直接使用了

Was this page helpful?
0 / 5 - 0 ratings