JimmyShoe
JimmyShoe

Reputation: 2299

vue emit data back to parent when using a slot

I have input on custom component and when i click on the next button on the wrapper component i need to emit details to the parent component.

How is this possible in vue?

wrapper.vue

<template>
    <div :id="contentId" class="mt-3">    
    <div>        
        <slot></slot>        
    </div>
    <b-row class="float-right">                
                <b-col>
                    <button cssClass="e-outline" v-on:click="btnNext">{{nextButtonText}}</button>  
                </b-col> 
            </b-row>     
    </div>

    </template>

parent.vue

<template>
    <div>
        <Wrapper contentId="1">
            <CustomComponent1 />
        </wrapper>
        <Wrapper contentId="2">
            <CustomComponent1 />
        </wrapper>
    </div>
    </template>

customComponent1.vue

<template>
    <div>
        <input v-model="name" />
<input v-model="name2" />
    </div>
</template>

code above is for illustrative purposes.

Upvotes: 3

Views: 6120

Answers (1)

Daniel
Daniel

Reputation: 35734

The problem is that the wrapper doesn't innately have access to data of the scoped component, therefore these links have to be created manually. There is no way to tell how many children or slots the component may have, so this kind of functionality is not part of the vue magic.

So in an example where you have parent App component, which holds a Wrapper that has a MyInput component in the slot...

MyInput

The MyInout component doesn't automatically update other components, so it needs to be setup to $emit the internal data.

This can be done using a watch, @change listener for the input, or some other way. You can emit multiple datum as they change, or use a single payload with all the data

this.$emit("input", myData);

App

The App needs to explicitly connect the data between MyInout and Wrapper

<Wrapper> <MyInput @input="onInput" slot-scope="{ onInput }" /> </Wrapper>

The magic/trick happens here, where we bind the input emit function of the input to the onInput function using slot-scope.

Wrapper

The wrapper then needs to listen to the events passed (via App) from Wrapper

<slot :onInput="onInput" />

where onInput is a method that would process the data

see example below
Edit Vue Template

I would recommend the following reading

Upvotes: 5

Related Questions