Reputation: 217
I'm brand new to vue js and I'm running into a bit of a problem. I have a list of information that I want to print out to the screen. Each item has a type and they're grouped together. Each group should have a header, but not each item. I have a working solution, but it feels like I'm missing something. Example below:
<div id="AnimalList">
<div v-for="animal in model.Animals">
<div class="header" v-if="showAnimalHeader(animal.Type)">
<span>{{animal.Type}}</span>
<hr/>
</div>
<span>{{animal.Type}} <label>Animal Name:</label> {{animal.Name}} <label>Color:</label> {{animal.Color}} </span>
</div>
</div>
var currentAnimal = '';
new Vue({
el: "#AnimalList",
data() {
return {
model: animalModel,
//currentAnimal: '',
};
},
methods: {
showAnimalHeader(animal) {
if (currentAnimal !== animal) {
currentAnimal = animal;
return true;
}
return false;
}
}
});
example data:
{type: dog, name: fido, color: black},
{type: dog, name: lassie, color: white and brown},
{type: cat, name: garfield, color: orange},
{type: cat, name: nermal, color: gray},
{type: fish, name: nemo, color: orange}
I don't like that I'm declaring currentAnimal outside the Vue. It feels like I'm doing this wrong. I tried using the commented data property and this.currentAnimal in the showAnimalHeader method, but then ran into the method firing off hundreds of times (resulting screen was still correct). I feel like I should be using computed instead of a method, but I'm struggling on how to get the correct Animal into the computed prop if that's the right way to do it so I know when the current animal has changed.
Upvotes: 1
Views: 41
Reputation: 11
I think the issue isn't necessarily in the Vue code, but in the data structure. I would move your "type" property into a parent object like so:
animalModel = [
{
"type": "dog",
"items": [
{
"name": "fido",
"color": "black"
},
{
"name": "lassie",
"color": "white and brown"
}
]
}, {
"type": "cat",
"items": [
{
"name": "garfield",
"color": "orange"
},
{
"name": "nermal",
"color": "gray"
},
]
}, {
"type": "fish",
"items": [
{
"name": "nemo",
"color": "orange"
}
]
}
]
This would enable you to put a loop inside of a loop in your vue file and achieve the desired result:
<div id="AnimalList">
<div v-for="animalGroup in model.Animals">
<div class="benefit-header">
<span>{{animalGroup.Type}}</span>
<hr/>
</div>
<span v-for="animal in animalGroup.items">{{animal.Type}} <label>Animal Name:</label> {{animal.Name}} <label>Color:</label> {{animal.Color}} </span>
</div>
</div>
This would remove any need for computed properties or methods for rendering this markup.
You would likely want to update the naming conventions accordingly, but that's how I would handle that dataset. Best of luck. Hope this helps!
Upvotes: 1