Loops
Loops are implemented with each
attribute as follows:
<my-component>
<ul>
<li each={ item in items } class={ item.done ? 'completed' : null }>
<input type="checkbox" checked={ item.done }> { item.title }
</li>
</ul>
<script>
export default {
items: [
{ title: 'First item', done: true },
{ title: 'Second item' },
{ title: 'Third item' }
]
}
</script>
</my-component>
The element with the each
attribute will be repeated for all items in the array. New elements are automatically added / created when the items array is manipulated using push()
, slice()
or splice
methods for example.
Looping custom components
Custom components can also be looped. For example:
<todo-item each="{ item in items }" { ...item }></todo-item>
The currently looped item properties can directly be passed to the looped tag.
Non-object arrays
The each directive uses internally Array.from
. This means that you can loop strings, Map, Sets containing also only primitive values:
<my-component>
<p each={ (name, index) in stuff }>{ index }: { name }</p>
<p each={ letter in letters }>{ letter }</p>
<p each={ meal in food }>{ meal }</p>
<script>
export default {
stuff: [ true, 110, Math.random(), 'fourth'],
food: new Map().set('pasta', 'spaghetti').set('pizza', 'margherita'),
letters: 'hello'
}
</script>
</my-component>
The name
is the name of the element and index
is the index number. Both of these labels can be anything that’s best suited for the situation.
Object loops
Plain objects can be looped via Object.entries
. For example:
<my-component>
<p each={ element in Object.entries(obj) }>
key = { element[0] }
value = { element[1] }
</p>
<script>
export default {
obj: {
key1: 'value1',
key2: 1110.8900,
key3: Math.random()
}
}
</script>
</my-component>
You can use Object.keys
and Object.values
if you just want to loop only fragments your object.
<my-component>
<p>
The Event will start at:
<time each={ value in Object.values(aDate) }>{ value }</time>
</p>
<script>
export default {
aDate: {
hour: '10:00',
day: '22',
month: 'December',
year: '2050'
}
}
</script>
</my-component>
Fragments loops
>=4.2.0
In some cases you may need to loop some html without having a particular wrapper tag. In that case you can use the tag that will be removed rendering just the html tags wrapped in it. For example:
<dl>
<template each={item in items}>
<dt>{item.key}</dt>
<dd>{item.value}</dd>
</template>
</dl>
This html fragments strategy is not exclusive to looping and can be used in conjunction with if
for any tag.
Loops advanced tips
Key
Adding the key
attribute to the looped tags you will provide a more precise strategy to track your items position. This will highly improve the loop performance in case your collections are immutable.
<loop>
<ul>
<li each={ user in users } key={ user.id }>{ user.name }</li>
</ul>
<script>
export default {
users: [
{ name: 'Gian', id: 0 },
{ name: 'Dan', id: 1 },
{ name: 'Teo', id: 2 }
]
}
</script>
</loop>
The key
attribute can be also generated in runtime via expressions
<loop>
<ul>
<li each={ user in users } key={ user.id() }>{ user.name }</li>
</ul>
<script>
export default {
users: [
{ name: 'Gian', id() { return 0 } },
{ name: 'Dan', id() { return 1 } },
{ name: 'Teo', id() { return 2 } }
]
}
</script>
</loop>