Illes Peter
Illes Peter

Reputation: 1674

Vue reactivity issue: slot in child component

I have the following setup:

<div id="app">
    {{ 'It updates here: ' + controlValue }}

    <modal v-bind:is-open="showModal" v-on:close-modal="showModal = false"
    >
        <template v-slot:body>
            {{ 'Doesn\'t update here ' + controlValue }}
            <control
                    name="tag-error-control"
                    type="radio"
                    v-bind:options="options"
                    v-model="controlValue"
            />
        </template>
    </modal>
</div>

When initially mounting components, controlValue is passed down correctly to Control. What's happening after that, is when clicking one of the radio buttons in Control, the value gets updated, input event is dispatched and controlValue in the main Vue component is updated, but it doesn't trickle down into the Modal and Control components (since Modal doesn't re-render). When I close the modal, then it re-renders and I can see the value trickling down to Modal and Control.

Edit

Did some more tests. Actually it doesn't relate to the Control at all. It's the same with a simple input.

<div id="app">
    {{ 'It updates here: ' + controlValue }}

    <modal v-bind:is-open="showModal" v-on:close-modal="showModal = false"
    >
        <template v-slot:body>
            {{ 'Doesn\'t update here ' + controlValue }}
                <input name="radio" type="radio" value="1" v-model="controlValue" />
                <input name="radio" type="radio" value="2" v-model="controlValue" />
                <input name="radio" type="radio" value="3" v-model="controlValue" />
                <input name="radio" type="radio" value="4" v-model="controlValue" />
        </template>
    </modal>
</div>

I ran out of ideas on how to fix this. What can I try next?

Upvotes: -2

Views: 718

Answers (1)

Illes Peter
Illes Peter

Reputation: 1674

So, as I suspected, the issue was with my slot scopes.

I had to look into https://v2.vuejs.org/v2/guide/components-slots.html#Scoped-Slots.

I changed my Modal component to have a slot prop on the slot.

<slot name="body" v-bind:slotProps="slotProps"></slot>

and then use it like this:

<div id="app">
    {{ 'It updates here: ' + controlValue }}

    <modal v-bind:is-open="showModal" v-bind:slot-props="controlValue" v-on:close-modal="showModal = false"
    >
        <template v-slot:body>
            {{ 'Doesn\'t update here ' + controlValue }}
            <control
                    name="tag-error-control"
                    type="radio"
                    v-bind:options="options"
                    v-model="controlValue"
            />
        </template>
    </modal>
</div>

Upvotes: 0

Related Questions