Vuejs passing data between parent child components using slots

I can create a parent child component like this:

Child Component

Vue.component('my-child', {
    template: '<div>{{value}}</div>',
    props: {
        value: {
            type: String,
            default: ""
        }
    }
});

Parent Component

Note how the my-child component is being referenced within the parent template.

Vue.component('my-parent', {
    template: '<div><span>Hello</span><my-child :value="value"></my-child></div>',
    data: function () {
        return {
            value: ""
        }
    },    
});

I can then use that like this:

<my-parent :value="ABC"></my-parent>

The value "ABC" gets passed through correctly to the child and displays as expected.

However, what I need to be able to do is as follows (basically I've pulled the my-child out of the parent template and back into HTML. I will have a number of different my-child components that I can use inside of my-parent):

<my-parent :value="ABC">
    <my-child></my-child>
</my-parent>

I changed the parent component to use a slot like this:

Vue.component('my-parent', {
    template: '<div><span>Hello</span><slot :value="value"></slot></div>',
    data: function () {
        return {
            value: ""
        }
    },    
});

The my-child template is getting picked up and displayed but the ABC value is not getting passed through to the my-child component as I would expect.

If I do this:

<my-parent :value="ABC">
    <my-child :value="value"></my-child>
</my-parent>

the my-child binding actually looks for 'value' on the root instance and not from my-parent, which is not what I want.

How can I pass the data down via the slot?

Upvotes: 0

Views: 5695

Answers (1)

Bert
Bert

Reputation: 82489

To pass data from a component to content in it's slot, you need to use a scoped slot.

In the parent component template, add the properties you want to pass to the child to the slot:

<div><span>Hello</span><slot :value="value"></slot></div>

Then in the template where the parent is used, use a template tag with the scope property.

<my-parent :value="ABC">
  <template scope="props">
    <my-child :value="props.value"></my-child>
  </template>
</my-parent>

Here is a working fiddle.

Upvotes: 1

Related Questions