Communication between Vue components

Keywords: Vue Javascript Attribute

Reference resources: https://juejin.im/post/5c77c4ae518825407505e262

This article mentions how three components communicate with each other

  • Communication between parent and child components
    • props and $emit are suitable for direct parent-child communication
    • $attrs and $listeners can communicate between grandparents
  • Communication of peer components
    • Ways of central event bus
const EventBus = new Vue();
Vue.prototype.$EventBus = EventBus;

Mode 1: props and $emit

props accomplish parent-child component communication well as a one-way data stream

  • One-way data flow means that data can only flow from the parent component to the child component through props, while the child component cannot modify the corresponding state of the parent component by modifying the data passed by props.
<body>
    <div id="app"></div>
    <script src="node_modules/vue/dist/vue.min.js"></script>
    <script  type="text/javascript">
        //Parent Component
        Vue.component('parent',{
            data(){
                return{
                    message:'hello'
                }
            },
            template:'<div>' +
                '<p>this is parent component</p>' +
                '<child :message="message" v-on:getChildData="getChildData"></child>' +
                '</div>',
            methods:{
                getChildData(val){
                    console.log(val);
                }
            }
        });
        //Subcomponents
        Vue.component('child',{
            template:'<div><input type="text" v-model="myMessage" @input="passData(myMessage)"/></div>',
            prop:['message'],
            data(){
                return{
                    myMessage:this.message
                }
            },
            methods:{
                passData(val){
                    this.$emit('getChildData',val);
                }
            }
        })
       new Vue({
           el:'#app',
           template:'<div><parent/></div>'s
       })
    </script>
</body>

Mode 2: $attrs and $listeners

The way a set of components communicates is only appropriate for direct parent-child components.For the disadvantage of Mode 1, attrs and attrs and attrs and listeners are provided to enable Component A to deliver messages directly to Component C

  • Implement component A to send messages to component C
<body>
    <div id="app"></div>
    <script src="node_modules/vue/dist/vue.min.js"></script>
    <script  type="text/javascript">
        Vue.component('A',{
            template: '<div><p>this is parent component</p><B :messagec="messagec" :message="message" ' +
                'v-on:getCData="getCData(messagec)" v-on:getChildData="getChildData(message)"></B></div>',
            data(){
                return{
                    messagec:'hello c',
                    message:'hello'
                }
            },
            methods:{
                getChildData(val){
                    console.log('This is from the component B Data' + val)
                },
                getCData(val){
                    console.log('This is from the component C Data' + val)
                }
            }
        });
        //Component B
        Vue.component('B',{
            <!-- CCan be triggered directly in a component getCData The reason is:BComponent Call CWhen component, use v-on Bound $listeners attribute -->
            <!-- adopt v-bind binding $attrs Properties,CComponents are directly available to APassed down from the component props(except BIn component props Declared) -->
            template:'<div>' +
                '<input type="text" v-model="mymessage" @input="passData(mymessage)">' +
                '<C v-bind="$attrs" v-on="$listener"></C>' +
                '</div>',
            props:['message'],
            data(){
                return{
                    mymessage:this.message
                }
            },
            methods:{
                passData(val){
                    this.$emit('getChildData',val)
                }
            }
        });
        //Component C
        Vue.component('C',{
            template:'<div><input type="text" v-model="$attrs.messagec" @input="passCData($attrs.messagec)"></div>',
            methods:{
                passCData(val){
                    //Trigger events in parent component A
                    this.$emit('getCData',val)
                }
            }

        })
        new Vue({
            el:'#app',
            template:'<div><A/></div>'
        })

    </script>
</body>

Mode 3: Central Event Bus (for peer components)

For communication between parent and child components, the above two methods can be fully implemented, but for two components that are not parent-child relationships, how can they be implemented?The project is small enough to use Central Event Bus Event

    <body>
        <div id="app"></div>
        <script src="vue.min.js"></script>
        <script>
            //EventBus creates a new Vue event bus object, then triggers the event via bus.$emit, and bus.$on listens for the triggered event.
            //Define Central Event Bus
            const EventBus = new Vue();
            
            //Assign the central event bus to Vue.prototype so that all components can access it
            Vue.prototype.$EventBus = EventBus;  //The main thing here is to add attributes to the prototype chain
            //Component A
            Vue.component('A',{
                template:`
                <div>
                    <p>this is A component</p>
                    <input type="text" v-model="mymessage" @input="passData(mymessage)" />
                </div>
                `,
                data(){
                    return{
                        mymessage: 'hello brother1'
                    }
                },
                methods:{
                    passData(val){
                        this.$EventBus.$emit('globalEvent',val)
                    }
                }
            });

            //Component B
            Vue.component('B',{
                template:`
                    <div>
                        <p>This is B component</p>
                        <p>assembly A Data passed in:{{brotherMessage}}</p>
                    </div>
                `,
                data(){
                    return{
                        brotherMessage:''
                    }
                },
                mounted(){
                    this.$EventBus.$on('globalEvent', (val) => {
                        this.brotherMessage = val;
                    })
                }
            })

            new Vue({
                el: '#app',
                template:`
                    <div>
                        <A />
                        <B />
                    </div>
                `
            })
        </script>
    </body>

Next I want to understand vuex in detail and take a better note. Now my notes are too messy ~

Posted by jlr2k8 on Thu, 16 May 2019 17:52:29 -0700