Reputation: 171
I have a addToCart component(child) on foodList component(parent). and there is another component Cart. i want to reset the addToCart component's counter value to 0 whenever i will empty my cart.
App.vue
data() {
return {
msg: "Welcome to Your Food Ordering App",
foodData:[],
cart:[],
reset:false
};
},
methods: {
emptyCart:function(){
this.reset = true;
this.cart = [];
}
}
foodList.vue
export default {
props:['foods','reset'],
data() {
return {
};
}
}
<addToCart :reset="reset"></addToCart>
addToCart
export default {
props:['food','reset'],
data(){
return {
counter:0
}
},
beforeMount() {
if(this.reset) {
this.counter = 0;
}
}
in app.vue I'm modifying the reset property to "true" and then passing it to foodList.vue, then passing it to addToCart.vue.
In addToCart.vue I'm checking if reset prop is true then set the counter to 0;
But this is not working.let me know where am I missing?
Please refer to this link for complete code.
Upvotes: 3
Views: 9295
Reputation: 4858
So basically you want to pass the state
over multiple components. There are multiple ways to achieve this. These are my three recommend ones.
In order to handle states
easier, you can make use of a centralized state management tool like vuex
: https://github.com/vuejs/vuex
This is what I recommend you, especially when it comes to bigger applications, where you need to pass the state over multiple levels of components. Trust me, this makes your life a lot easier.
The most basic way to communicate with your child components is property binding. But especially when it comes to multi-level communication it can get quite messy.
In this case, you would simply add counter
to both of your child components props
array like this:
foodList.vue (1. Level Child Component)
export default {
props:['foods','reset', 'counter'],
// ... your stuff
}
And include the component like this:
<foodList :counter="counter"></foodList>
addToCart.vue (2. Level Child Component)
export default {
props:['food','reset', 'counter'],
// ... your stuff
}
And finally include the component like this:
<addToCart :reset="reset" :counter="counter"></addToCart>
As a last step, you can specify counter
in the data
object of your root component and then modify it on a certain event
. The state
will be passed down.
App.vue
data() {
return {
// ... your stuff
counter: 0,
};
},
methods: {
emptyCart:function(){
// ... your stuff
this.counter = 0; // reset the counter from your parent component
}
}
As a third option, you could make use of Vue's event bus. This is the option I personally choose for applications, which get too messy with simple property binding, but still are kind of too small to make us of Centralized State management
.
To get started create a file called event-bus.js
and then add the following code to it:
import Vue from 'vue';
export const EventBus = new Vue();
Now you can simply trigger events from your parent Component like this:
App.vue
import { EventBus } from './event-bus.js'; // check the path
export default {
// ... your stuff
methods: {
emptyCart:function(){
// ... your stuff
EventBus.$emit('counter-changed', 0); // trigger counter-changed event
}
}
}
And then listen to the counter-changed
event in your child component.
addToCart.vue
import { EventBus } from './event-bus.js';
export default {
// ... your stuff
created() {
EventBus.$on('counter-changed', newCounter => {
this.counter = newCounter;
});
}
}
Learn more about the event bus: https://alligator.io/vuejs/global-event-bus/
Upvotes: 7