Hello-World
Hello-World

Reputation: 9555

Why wont the component respond to the custom event?

I am emitting an event called emit-event-main2-counter in Main2.vue

Why will the data cntr in Bottom.vue not update?

App.vue

<template>
  <div class="app">
    <Main2 />
    <Bottom/>
  </div>
</template>

<script>
import Main2 from "./components/Main2";
import Bottom from "./components/Bottom";

export default {
  components: {
    Main2,
    Bottom
  },

}
</script>

<style scoped>
  h1 {
    color: red;
  }
</style>

Main2.vue

<template>
    <div>
        main2 template <span class="text1">{{message}}</span>
        <button type="button" v-on:click="btnClickButton">my click</button>
        <div>{{counter}}</div>

    </div>
</template>

<script>
    import appInput from "./appInput.vue";
    export default {
        data: () => {
            return {
                message: "theText",
                counter: 0,
            }
        },
        components: {
           appInput,
       },
        methods: {
            btnClickButton(e) {
                this.$root.$emit('emit-event-main2-counter', this.counter)
                console.log('button');
                this.counter +=1;
            }
        }

    }
</script>

<style scoped>
.text1 {
    color:red;
}
.text2 {
    color:blue;
}
</style>

Bottom.vue

<template>
  <div  class="Bottom" v-on:emit-event-main2-counter="cntr = $event">
      bottom text and cntr ({{cntr}})
  </div>
</template>

<script>

export default {
    data: () => {
        return {
            cntr: 0
        }
    },
}
</script>

<style scoped>

</style>

Upvotes: 0

Views: 53

Answers (2)

ssc-hrep3
ssc-hrep3

Reputation: 16079

If you want to use root events, you need to emit the event with this.$root.$emit() and also listen to the event on the root like this: this.$root.$on().

You should use it directly in the script part. Listen to the root event e.g. in the created() hook and then disable it with $off in the beforeDestroy() hook.


However, I wouldn't encourage you to use $root events. It is usually better to communicate between the components like @BoussadjraBrahim proposed in his answer.

If you have a more complex application, it makes sense to take a look at Vuex and store the complete state in the Vuex store. By doing this, you can watch the global application state in the components and react if it changes. In this scenario, you would use the Vuex store instead of a root EventBus.

Upvotes: 2

Boussadjra Brahim
Boussadjra Brahim

Reputation: 1

You could emit an event to parent from Main2 having as parameters this.counter and in the parent one receive that and pass it through props to Bottom

In Main2 :

this.$emit("emit-event-main2-counter",this.counter);

in the parent component :

  <template>
   <Main2 v-on:emit-event-main2-counter="sendToBottom"/>
   <Bottom :cntr="pcounter"/>
  ....
  </template>


  data:{
   pcounter:0
    },
  methods:{
       sendToBottom(c){
        this.pcounter=c
          }
      }

Bottom should have property called cntr

  props:["cntr"]

Bottom.vue

     <template>
      <div  class="Bottom" >
          bottom text and cntr ({{cntr}})
      </div>
    </template>

  <script>

    export default {
           props:["cntr"],
         data: () => {
             return {
                }
            },
       }
     </script>

Upvotes: 3

Related Questions