Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Event from parent to child component

I have event that is generated in parent component and child has to react to it. I know that this is not recommended approach in vuejs2 and i have to do a $root emit which is pretty bad. So my code is this.

<template>
    <search></search>
    <table class="table table-condensed table-hover table-striped" v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="10">
        <tbody id="trans-table">
            <tr v-for="transaction in transactions" v-model="transactions">
                <td v-for="item in transaction" v-html="item"></td>
            </tr>
        </tbody>
    </table>
</template>

<script>
    import Search from './Search.vue';

    export default {
        components: {
            Search
        },
        data() {
            return { 
                transactions: [], 
                currentPosition: 0 
            }
        },
        methods: {
            loadMore() {
                this.$root.$emit('loadMore', {
                    currentPosition: this.currentPosition
                });
            }
        }
    }
</script>

As You can see loadMore is triggered on infinite scroll and event is being sent to child component search. Well not just search but since it's root it's being broadcast to everyone.

What is better approach for this. I know that i should use props but I'm not sure how can i do that in this situation.

like image 504
madeye Avatar asked Apr 06 '17 13:04

madeye


People also ask

How do you pass event from parent component to child component?

In the parent component, create a callback function. This callback function will retrieve the data from the child component. Pass the callback function to the child as a props from the parent component. The child component calls the parent callback function using props and passes the data to the parent component.

How do you fire event from parent to child in LWC?

In the case of Child to Parent communication, it is a bit more complicated. From the child component, we will pass the value to the parent component using CustomEvent. Note: The CustomEvent constructor has one required parameter: a string, which refers to the event type.

How do you communicate between parent and child components?

The <parent-component> serves as the context for the <child-component> . @Input() and @Output() give a child component a way to communicate with its parent component. @Input() lets a parent component update data in the child component.

How do I send my child an event to a parent?

Prepare Child component to emit data Furthermore, we need to know that the child component uses the @Output() property to raise an event (by using an EventEmitter) to notify the parent of the change. @Output() is a decorator that marks a class field (that has to be named) as an output property.


1 Answers

Just have a variable (call it moreLoaded) that you increment each time loadMore is called. Pass that and currentPosition to your search component as props. In Search, you can watch moreLoaded and take action accordingly.

Update
Hacky? My solution? Well, I never! ;)

You could also use a localized event bus. Set it up something like this:

export default {
    components: {
        Search
    },
    data() {
        return {
            bus: new Vue(),
            transactions: [], 
            currentPosition: 0 
        }
    },
    methods: {
        loadMore() {
            this.bus.$emit('loadMore', {
                currentPosition: this.currentPosition
            });
        }
    }
}

and pass it to Search:

<search :bus="bus"></search>

which would take bus as a prop (of course), and have a section like

created() {
    this.bus.$on('loadMore', (args) => {
        // do something with args.currentPosition
    });
}
like image 81
Roy J Avatar answered Oct 12 '22 14:10

Roy J