Vue 2 - Communication between components (sending

2019-09-16 10:08发布

问题:

So I working on app in Vue. I have problem with sending and receiving data between components. Already tried with $dispatch/$broadcast, $emit/$on but still now working. I want to send selected active_club from ClubSelection.vue to vue_main.js.

Vue version: 2.0.3

Structure of my app:

  1. vue_main - main Vue file
    1. HeaderElement.vue (child of vue_main)
      1. ClubSelection.vue (child of HeaderElement)

Need to send active_club from ClubSelection to vue_main.

ClubSelection.vue

    <script>

    export default{
        props: [
            'club', 'title'
        ],
        created(){

            //Get club list
            this.$http.get('/api/clubs', function(data) {
                this.clubs = data;
                console.log(data);

                //read active club from parent
                this.selected = this.$parent.$parent.active_club;
            });

        },
        data(){
            return{
                clubs: [],
                selected: null,
            }
        },
        watch: {
            selected: function(v) {
                this.club = v;

                //Post to database selected club
                this.$http.post('/api/clubs/' + v + '/active')

            },
            club: function(v) {
                this.selected = v;

                //Change active_club at parent (THIS NOT WORKING)
//              this.$emit('active_club', v);
//              this.$parent.active_club = v;
                club.$emit('active_club', v);

            },
        }

    }
</script>

vue_main.js

    const app = new Vue({
    router,
    data() {
        return {
            user: [],
            active_club: null,
            ranking: null
        }
    },
    created: function() {
        var self = this;

        this.$http.get('/api/users/me', function(data) {
            this.user = data;
            self.active_club = data.active_club;

        })

    }


}).$mount('#app');

const club = new Vue();

//THIS NOT WORKING
club.$on('active_club', function (id) {

    alert(id)
    this.active_club = id;
});

Errors:

Vue warn]: Error in watcher "club" (found in component )

vue_main.js:16924 Uncaught (in promise) ReferenceError: club is not defined

I have tried many set ups, this is one of them. How to make this working?

回答1:

$dispatch and $broadcast are deprecated in Vue 2.0.

In your case, what you need is communication between a parent component and child component. When a child $emits an event, parent can listen to it by providing a method in template markup itself, using v-on:parentMethod() as follows:

<child-component v-on:child-event="handlerMethod"></child-component>

The above markup is done inside parent component's template. And the parent component needs to have that handlerMethod in its methods.

Here is a sample "parent-child communication" question on Stackoverflow, which has a jsFiddle example also: Delete a Vue child component

You may use the above answer as reference to implement $emit in your app.

Edit: Additional Notes

I forgot to mention the note about three level hierarchy you have. In your app, you have the following hierarchy:

parent: vue_main

child 1: HeaderElement

child 1.1: ClubSelection

For sending events from ClubSelection to vue_main, you may either use non parent-child communication method or you can relay the event using the intermediate HeaderElement.

Here is how the event relay can work:

  • Step 1: ClubSelection sends a $emit, which is received by HeaderElement using v-on.
  • Step 2: The handlerMethod in HeaderElement does a this.$emit, which can be received by your main template using another v-on.

While the above may look a bit convoluted, it is much more efficient than broadcasting to every single component in the app, as it is generally done in Angualr 1.x or other frameworks.