Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Share data across different components in Vuejs

Given the mini Vuejs app down below.

When I click one of my increment/decrement buttons, the value within the "counter" component updates but the value inside "alphabet" doesn't.
Any ideas on how can I share the same data across those two components so that they automatically update ?

var counter = Vue.extend({
    props: ['start'],
    template: '#counter',
    data: function() {
      return {
        value: this.start
      }
    },
    methods: {
      increment: function() {
        this.value++
      },
      decrement: function() {
        this.value--
      }
    }
  });

  var alphabet = Vue.extend({
    props: ['value'],
    template: '#alphabet',
    data: function() {
      return {
        value: 0
      }
    }
  });

  new Vue({
    el: '#app',
    data: {
      val: 5
    },
    components: {
      counter: counter,
      alphabet: alphabet
    }
  });
<script id="counter" type="text/template">
  <button @click="increment">+</button> {{ value }}
  <button @click="decrement">-</button>
</script>
<script id="alphabet" type="text/template"> {{ value }} </script>
<div id="app">
  <counter :start="val"></counter>
  <alphabet :value="val"></alphabet>
</div>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.17/vue.js"></script>
like image 678
skay- Avatar asked Mar 15 '16 16:03

skay-


People also ask

How do you pass data between two child components in Vue?

You can pass the data as a prop, just dont modify the prop in the child component. If you're going to modify a property in the child, set it as a data attribute and then emit an event when it changes. Listen for that event in parent and update the data as necessary.

How can I get data from another component?

For passing the data from the child component to the parent component, we have to create a callback function in the parent component and then pass the callback function to the child component as a prop. This callback function will retrieve the data from the child component.


2 Answers

There were 2 issues with the way you set it up. Here it is working: https://jsfiddle.net/j9hua7c8/

First issue was in the counter component, you created a new variable called value and it a value of this.start. This took the value of start and assigned it to value, but since value was a new variable it was no longer sync'd to start. Updated version:

var counter = Vue.extend({
  props: ['value'],
  template: '#counter',
  methods: {
    increment: function() {this.value++},
    decrement: function() {this.value--}
  }
});

Second thing is, in order to have a child variable sync two-ways, you need to use the .sync modifier on the binding. By default, they are only one-way bindings. Updated:

<counter :value.sync="val"></counter>

You can also use $dispatch and $broadcast to communicate between parent and child components if that is better for your use case.

like image 189
Jeff Avatar answered Sep 18 '22 22:09

Jeff


You have two choices.

1 Manually sync your values

in your increment and decrement functions add this sentence

this.$parent.val = this.value;

and make your alphabet value equal to the parent val

computed: {
    value: function() {
        return this.$parent.val;
    }
  }

resulting in this fiddle

2 Use vuex to keep a global state of your data

With vuex you can store a common state for all your components. This state will be reactive, so will be updated for every component when you change its value. This could be an overkill for your use case, but is definitly a choice to keep in mind

like image 27
Yerko Palma Avatar answered Sep 21 '22 22:09

Yerko Palma