Iteration - sikaeducation/vue-curriculum GitHub Wiki
Iteration in templates is achieved through the v-for
directive:
<template>
<ul>
<li
v-for="item in list"
:key="item.id"
>{{ item.content }}</li>
</ul>
</template>
The syntax is similar to JavaScript's for..in
statement. Some notes:
- You must include the
:key
binding, which needs to be set to some unique value. IDs are a natural choice, but in the absence of an available ID any unique attribute will do. - If you also need the index, you can get it like so:
v-for="(index, item) in list"
- The item and the index in a
v-for
are scoped to the element you put the directive on and anything inside of them
You can also hard-code items in a list, including multiple lists, etc. This is especially common for making disabled defaults in drop-downs or separators:
<template>
<select>
<option disabled>Please select an option below:</option>
<option disabled>North America</option>
<option v-for="countries in northAmericanCountries" :key="country.code">{{ country.name }}</option>
<option disabled>Europe</option>
<option v-for="countries in europeanCountries" :key="country.code">{{ country.name }}</option>
</select>
</template>
It may be tempting to make the key the index:
<li v-for="(item, index) in list" :key="index"></li>
This doesn't work. Don't do it. Vue uses these keys to figure out which items to re-render, and it can't do that if the key is generated by the looping mechanism itself.
It's easy to forget the binding in the template:
<li v-for="item in list" key="item.id"> // No!
<li v-for="item in list" :key="item.id"> // Yes!
If you leave off the :
, you'll set the key to the static string "item.id"
, which is not what you're looking for.
The same element should never have a v-if
and a v-for
:
<template>
<ul>
<li
v-for="item in list"
:key="item.id"
v-if="list.length > 0"
>{{ item.text }}</li>
<ul>
</template>
Instead, try to split them up:
<template>
<ul v-if="list.length > 0">
<li
v-for="item in list"
:key="item.id"
>{{ item.text }}</li>
<ul>
</template>
Or use a computed property to make a custom list:
<template>
<ul>
<li
v-for="item in activeList"
:key="item.id"
>{{ item.text }}</li>
<ul>
</template>
<script>
export default {
computed: {
list() {
return [...]
},
activeList() {
return this.list.filter(item => item.isActive)
},
},
}
</script>
Using this array:
[{
id: 1,
label: "Apple",
},{
id: 2,
label: "Banana",
},{
id: 3,
label: "Carrot",
}]
Render each one in a list item.