Several items of the same type can be produced by reusing components with v-for.
The ability to dynamically assign props depending on values from an array is also quite useful when producing elements using v-for from a component.

Building Components Using Vue’s v-for
Next, we will use v-for to build component elements based on an array containing the names of food items.
App.vue:
<template>
<h1>Food</h1>
<p>Components created with v-for based on an array.</p>
<div id="wrapper">
<food-item
v-for="x in foods"
v-bind:food-name="x"/>
</div>
</template>
<script>
export default {
data() {
return {
foods: ['Apples','Pizza','Rice','Fish','Cake']
};
}
}
</script>
FoodItem.vue:
<template>
<div>
<h2>{{ foodName }}</h2>
</div>
</template>
<script>
export default {
props: ['foodName']
}
</script>
Shorthand V-Bind
We utilize v-bind to dynamically bind props, and since we will be using v-bind a lot more now than in the past, we will use the v-bind: shorthand : in the remainder of this lesson.
The “key” characteristic
Because of the way Vue updates elements produced using v-for, issues may appear if we make changes to the array after the elements have been formed. Because Vue reuses elements to maximize efficiency, removing an item may result in the reuse of already-existing elements rather than the creation of new ones, and element properties may no longer be accurate.
The lack of a unique identifier is the cause of improper element reuse, and that is precisely why we use the key attribute: to enable Vue to distinguish between elements.
First, let’s create a web page containing foods using v-for to display the food name, description, favorite food image, and button to change favorite status. Without the key property, we will create erroneous behavior.
Example
App.vue:
<template>
<h1>Food</h1>
<p>Food items are generated with v-for from the 'foods' array.</p>
<div id="wrapper">
<food-item
v-for="x in foods"
:food-name="x.name"
:food-desc="x.desc"
:is-favorite="x.favorite"/>
</div>
</template>
<script>
export default {
data() {
return {
foods: [
{ name: 'Apples',
desc: 'Apples are a type of fruit that grow on trees.',
favorite: true },
{ name: 'Pizza',
desc: 'Pizza has a bread base with tomato sauce, cheese, and toppings on top.',
favorite: false },
{ name: 'Rice',
desc: 'Rice is a type of grain that people like to eat.',
favorite: false }
{ name: 'Fish',
desc: 'Fish is an animal that lives in water.',
favorite: true }
{ name: 'Cake',
desc: 'Cake is something sweet that tastes good.',
favorite: false }
]
};
}
}
</script>
<style>
#wrapper {
display: flex;
flex-wrap: wrap;
}
#wrapper > div {
border: dashed black 1px;
flex-basis: 120px;
margin: 10px;
padding: 10px;
background-color: lightgreen;
}
</style>
FoodItem.vue:
<template>
<div>
<h2>
{{ foodName }}
<img src="/img_quality.svg" v-show="foodIsFavorite">
</h2>
<p>{{ foodDesc }}</p>
<button v-on:click="toggleFavorite">Favorite</button>
</div>
</template>
<script>
export default {
props: ['foodName','foodDesc','isFavorite'],
data() {
return {
foodIsFavorite: this.isFavorite
}
},
methods: {
toggleFavorite() {
this.foodIsFavorite = !this.foodIsFavorite;
}
}
}
</script>
<style>
img {
height: 1.5em;
float: right;
}
</style>
Let’s make a button that eliminates the array’s second element to demonstrate the necessity of the key attribute. This occurs when the favorite picture is moved from the ‘Fish’ element to the ‘Cake’ element without the key property, which is incorrect:
Example
The addition of a button is the only change from the prior example:
<button @click="removeItem">Remove Item</button>
and a method:
methods: {
removeItem() {
this.foods.splice(1,1);
}
}
in App.vue.
As previously said, Vue optimizes the page by reusing elements, but it is unable to completely distinguish between them, which is the reason why the favorite picture switches from “fish” to “cake” when an element is deleted. For this reason, while producing items using v-for, we need always add the key attribute to mark each element uniquely. This issue is resolved when the key attribute is used.
Since the array element index varies when array elements are added and removed, we do not utilize it as the key attribute value. Since the food products already have unique names, we can use that instead of creating a new data property to store a unique value for each item, such as an ID number:
Example
To solve the issue and uniquely identify each element produced using v-for, we simply need to add one line to App.vue:
<food-item
v-for="x in foods"
:key="x.name"
:food-name="x.name"
:food-desc="x.desc"
:is-favorite="x.favorite"
/>