Doli Dod
Doli Dod

Reputation: 1

Sibling component communication not working in vue

I am trying to send this.TC from typing.js to ending-page.js which are sibling components. Emits and event hubs not working. But emit from typing.js to parent works as I want. (There will be only one more call in this app, so i don't want use Vuex if it isnt necessary for this - i want to do it with simple emits ) Here's my code:

Parent:

      <template>
    <div id = "app">

    <typing v-if = "DynamicComponent === 'typing'" />
    <ending_page v-else-if = "DynamicComponent === 'ending_page'" />

    </div>
  </template>
  <script>

  /* Importing siblings components to parent component */
  import typing from './components/typing/index.vue'
  import ending_page from './components/ending-page/index.vue'

  export default {


    name: 'app',
    components: {
      typing,
      ending_page
    },

    data() {
      return {

        DynamicComponent: "typing",

      };
    },

    methods: {

      updateDynamicComponent: function(evt, data){

        this.DynamicComponent = evt;

      },

    },


  };

  </script>

typing.js:

      import { eventBus } from "../../main";

  export default {


    name: 'app',
    components: {

    },

    data() {
      return {

        /* Text what is in input. If you write this.input = "sometext" input text will change (It just works from JS to HTML and from HTML to JS) */
        input: "",

        /* Object of TypingCore.js */
        TC: "somedata",

        /* Timer obejct */
        timer: null,
        is_started: false,
        style_preferences: null,


      };
    },


      ICallThisFunctionWhenIWantToEmitSomething: function(evt) {

          /* Sending data to ending_page component */
          this.$root.$emit('eventname', 'somedata');

          /* Calling parent to ChangeDynamicComponent && sending TC.data what will be given to ending_page (I think it looks better with one syntax here) */
          this.$emit('myEvent', 'ending_page', this.TC.data);

        }

      },




  };

ending-page.js:

      import { eventBus } from "../../main";

  export default {
    name: 'ending-page',
    components: {},

    data () {
      return {
        data: "nothing",
      }
    },

    computed: {

    },

    props: {

    },

    methods: {


    },

    /* I know arrow functions etc but i was trying everyting */
    created: function () {
      this.$root.$on('eventname', function (data) {
          console.log(data)
          this.title = data
          this.$nextTick()
      })
    }

  }

Upvotes: 0

Views: 2036

Answers (3)

lmarqs
lmarqs

Reputation: 1471

It is an example of how to share data between siblings components.

Children components emits events to parent. Parent components send data to children.

So, the parent has the property title shared between the children. When typing emits the input event the directive v-modelcapture it an set the value on parent.

Ref:

https://v2.vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow

https://v2.vuejs.org/v2/guide/components.html#Using-v-model-on-Components

https://benjaminlistwon.com/blog/data-flow-in-vue-and-vuex/

Vue.component('typing', {
  props: {
    value: ''
  },
  template: '<button @click="emit">Click to change</button>',
  methods: {
    emit() {
      this.$emit('input', `changed on ${Date.now()}`);
    }
  }
});

Vue.component('ending-page', {
  props: {
    title: ''
  },
  template: '<div>{{ title }}</div>',
});

var app = new Vue({
  el: '#app',
  data() {
    return {
      title: 'unchanged',
    };
  },
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <typing v-model="title"></typing>
  <ending-page :title="title"></ending-page>
</div>

Upvotes: 1

Borisu
Borisu

Reputation: 848

I like what Jeffrey Way suggested once, just create a global events object (which accidentally can be another Vue instance) and then use that as an event bus for any global communication.

window.eventBus = new Vue();

// in components that emit:
eventBus.$emit('event', data);

// in components that listen
eventBus.$on('event');

Upvotes: 0

mohit dutt
mohit dutt

Reputation: 31

One can try communication using vuex, the data you want to share make it on this.$store.state or if recalling for functions use mutation(sync functions) and actions(async functions) https://vuex.vuejs.org/

Upvotes: 0

Related Questions