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>
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.
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.
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.
You have two choices.
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With