Reputation: 102
I'm trying to share data stored in a variable favorite_count
within the Favorites component in Favorites.vue
file. I want to share that data with the App Component in the App.vue
file but I'm not able to. I would want that if I change the value of favorite_count
in the Favorites component, it changes in the App Component. Done quite some research on the web but no success yet. Any ideas on what I could be doing wrong?
Favorites.vue file
<template>
<div class="row m-5">
<h3 class="col-8">Your Favorites</h3>
<div class="col-4">
<p class="pull-right m-1">Picks
<span >{{ favorite_count }}</span> / 5</p>
</div>
<hr>
</div>
</template>
<script>
export default {
name: 'favorites',
data() {
return {
favorite_count: 5,
}
},
methods: {
changeFavoriteCount() {
this.favorite_count = this.favorite_count + 2;
},
emitToParent (event) {
this.$emit('childToParent', this.favorite_count)
}
}
}
</script>
App.vue
file
<template>
<div class="navbar navbar-expand-md navbar-dark bg-primary">
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav">
<li class="nav-item">
<router-link to="/favorites" class="btn btn-info">
Favorites ( {{ favorite_count }} )
</router-link>
</li>
</ul>
</div>
</div>
</template>
<script>
import Favorites from './components/Favorites.vue'
export default {
name: 'App',
components: {
Favorites
},
data () {
return {
favorite_count: 0,
}
}
}
</script>
Upvotes: 3
Views: 27303
Reputation: 706
If you are going to use <router-view>
later in your application, I would suggest this solution
If you were going to include Favorites
inside <template>
in App.vue
, you can use props:
1. Declare your 'shared' variable in the parent component (App.vue)
data () {
return {
favorite_count: 0,
}
},
2. Define props in your child component (Favorites.vue)
export default {
props: { favorite_count: Number },
...
}
3. Pass favorite_count
as prop to Favorites
<template>
...
<Favorites :favorite_count="favorite_count" ... />
</template>
If you will need to update favorite_count
- emit an event to parent component. More about it in Vue docs
Edit: Just to clarify: If you are going to update favorite_count
from Favorites.vue, you need to emit an event to App.vue to avoid mutating props.
That also means you need to move your changeFavoriteCount()
function to App.vue and apply a listener to your child component which will call this function:
// App.vue
<template>
...
<Favorites
@your-update-event="changeFavoriteCount"
:favorite_count="favorite_count" ...
/>
</template>
...
changeFavoriteCount(newVal) {
this.favorite_count = newVal;
},
Upvotes: 9
Reputation: 525
change your Favourite.vue
file like this
<template>
<div class="row m-5">
<h3 class="col-8">Your Favorites</h3>
<div class="col-4">
<p class="pull-right m-1">
Picks <span>{{ favorite_count }}</span> / 5
<button @click="changeFavoriteCount">Click me to change favorite_count</button>
</p>
</div>
<hr />
</div>
</template>
<script>
export default {
name: "favorites",
data() {
return {
favorite_count: 5,
};
},
methods: {
changeFavoriteCount() {
this.favorite_count = this.favorite_count + 2;
this.emitToParent();
},
emitToParent() {
this.$emit("childToParent", this.favorite_count);
},
},
};
</script>
and the App.vue file like this
<template>
<div class="navbar navbar-expand-md navbar-dark bg-primary">
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav">
<li class="nav-item">
<router-link to="/favorites" class="btn btn-info">
<Favorites @childToParent="updateFavorite" />
Favorites ( {{ favorite_count }} )
</router-link>
</li>
</ul>
</div>
</div>
</template>
<script>
import Favorites from './components/Favorites.vue'
export default {
name: 'App',
components: {
Favorites
},
data () {
return {
favorite_count: 0,
}
},
methods: {
updateFavorite(data) {
this.favorite_count = data;
},
},
}
</script>
Upvotes: 2