Search code examples
vuejs2vuex

How to fire an event from child component in vuex to any parent


So I have Component "X" as Parent Component Or Component "Y" as
Parent Component, "a" as child component fire one or many events
Any child sibling or parent of "a" or "a" Itself can use that event
I want to use "a" as an independent component

So I Have "X" component with its own

   state
   mutations
   actions 
   getters

And I have "a" component with its own

state    
mutations    
actions     
getters

"a" a.vue file looks like this

<template>
<div>
<app-select 
 @change.native="someevent()" 
 name="lineup_id" 
 v-model="$store.state.form.id" label="Select Id" 
:options="options"
 />
</div>
</template>
import AppSelect from "../AppSelect.vue";
export default {
  data() {
    return {
      options:[]
    };
  },
  components: {
    AppSelect,
  },
}

So I want to fire change event from child "a"
"X" and "Y" any parent get that event and do something with that event
I know how to do it with VUE


Solution

  • Fist : Don't use $state to get properties, use mapState

    <template>
      <div>
        <app-select 
          @change.native="someevent()" 
          name="lineup_id" 
          v-model="explicitPropertyName" label="Select Id" 
          :options="options"
        />
      </div>
    </template>
    <script>
    import AppSelect from "../AppSelect.vue";
    import { mapState } from 'vuex'
    
    export default {
      computed : {
          ...mapState(['explicitPropertyName'])
      }
      data() {
        return {
          options:[]
        };
      },
      components: {
        AppSelect,
      },
    }
    </script>
    

    Second : Use bus event, see an example

    Vue.config.productionTip = false
    Vue.config.devtools = false
    
    Vue.prototype.$eventBus = new Vue()
    
    const componentA = {
      template : `<button @click="emitMethod">Component A emit</button>`,
      methods: {
        emitMethod () {
           this.$eventBus.$emit('EVENT_NAME_FROM_A', { id: 12, pseudo: "Unicorn power A"});
        }
      },
      mounted () {
        this.$eventBus.$on('EVENT_NAME_FROM_B', function (payload) {
           console.log('Emitted from component B, received in Component A', payload);
        });
      }
    }
    
    const componentB = {
      template : `<button @click="emitMethod">Component B emit</button>`,
      methods: {
        emitMethod () {
           this.$eventBus.$emit('EVENT_NAME_FROM_B', { id: 12, pseudo: "Unicorn power"});
        }
      },
      mounted () {
        this.$eventBus.$on('EVENT_NAME_FROM_A', function (payload) {
           console.log('Emitted from component A, received in Component B', payload);
        });
      }
    }
    
    const vm = new Vue({ 
      el: "#app",
      components : {
        componentA,
        componentB
      },
      mounted () {
        this.$eventBus.$on('EVENT_NAME_FROM_B', function (payload) {
           console.log('Emitted from component B, received in Parent', payload);
        });
        
        this.$eventBus.$on('EVENT_NAME_FROM_A', function (payload) {
           console.log('Emitted from component A, received in Parent', payload);
        });
      }
    })
    <!DOCTYPE html>
    <html>
       <head>
          <title></title>
       </head>
       <body>
          <div id="app">
             <div>
                <component-b></component-b>
                <component-a></component-a>
             </div>
          </div>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
       </body>
    </html>