Referencing the live demo code here:
https://codesandbox.io/s/vue-template-r26tg
Let's say I have a Vuex store with the following data:
const store = new Vuex.Store({
state: {
categories: [
{
name: "Category A",
items: [{ name: "Item 1" }, { name: "Item 2" }, { name: "Item 3" }]
},
{
name: "Category B",
items: [{ name: "Item A" }, { name: "Item B" }, { name: "Item C" }]
},
{
name: "Category C",
items: [{ name: "Item !" }, { name: "Item @" }, { name: "Item #" }]
}
]
}
});
And I have an App.vue, Category.vue and Item.vue that are set up so that they are rendered like so:
//App.vue
<template>
<div id="app">
<Category v-for="(category, index) in categories" :category="category" :key="index"/>
</div>
</template>
<script>
export default {
components: { Category },
computed: {
...mapState(["categories"])
}
};
</script>
//Category.vue
<template>
<div class="category">
<div class="header">{{ category.name }}</div>
<Item v-for="(item, index) in category.items" :item="item" :key="index"/>
</div>
</template>
<script>
export default {
components: { Item },
props: {
category: { type: Object, required: true }
}
};
</script>
//Item.vue
<template>
<div class="item">
<div class="name">{{ item.name }}</div>
<div class="delete" @click="onDelete">✖</div>
</div>
</template>
<script>
export default {
props: {
item: { type: Object, required: true }
},
methods: {
onDelete() {
this.$store.commit("deleteItem", this.item);
}
}
};
</script>
In other words, App.vue gets the list of categories from Vuex, then passes it down to Category.vue as a prop for each category, then Category.vue passes down category.items to Item.vue as a prop for each item.
I need to delete an item when the delete button next to it is clicked:
However, at the Item.vue level, I only have access to the item, but not the category. If I send the item to Vuex, I have no way of telling which category it belongs to. How do I get a reference to the category so that I can delete the item from it using Vuex?
I can think of two ways:
Add a parent reference back to the
categoryfor eachitem. This is undesirable not only because I'd have to massage theitemdata, but also because it introduces a circular reference that I'd rather not have to deal with in other parts of the app.Emit an event from
Item.vueup toCategory.vueand letCategory.vuehandle the Vuex call for deletion. This way the category and the to-be-deleted item are both known.
Is there a better way of handling this kind of deletion?
