Loops

Loops are implemented with each attribute as follows:

  1. <my-component>
  2. <ul>
  3. <li each={ item in items } class={ item.done ? 'completed' : null }>
  4. <input type="checkbox" checked={ item.done }> { item.title }
  5. </li>
  6. </ul>
  7. <script>
  8. export default {
  9. items: [
  10. { title: 'First item', done: true },
  11. { title: 'Second item' },
  12. { title: 'Third item' }
  13. ]
  14. }
  15. </script>
  16. </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:

  1. <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:

  1. <my-component>
  2. <p each={ (name, index) in stuff }>{ index }: { name }</p>
  3. <p each={ letter in letters }>{ letter }</p>
  4. <p each={ meal in food }>{ meal }</p>
  5. <script>
  6. export default {
  7. stuff: [ true, 110, Math.random(), 'fourth'],
  8. food: new Map().set('pasta', 'spaghetti').set('pizza', 'margherita'),
  9. letters: 'hello'
  10. }
  11. </script>
  12. </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:

  1. <my-component>
  2. <p each={ element in Object.entries(obj) }>
  3. key = { element[0] }
  4. value = { element[1] }
  5. </p>
  6. <script>
  7. export default {
  8. obj: {
  9. key1: 'value1',
  10. key2: 1110.8900,
  11. key3: Math.random()
  12. }
  13. }
  14. </script>
  15. </my-component>

You can use Object.keys and Object.values if you just want to loop only fragments your object.

  1. <my-component>
  2. <p>
  3. The Event will start at:
  4. <time each={ value in Object.values(aDate) }>{ value }</time>
  5. </p>
  6. <script>
  7. export default {
  8. aDate: {
  9. hour: '10:00',
  10. day: '22',
  11. month: 'December',
  12. year: '2050'
  13. }
  14. }
  15. </script>
  16. </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

  1. <dl>
  2. <template each={item in items}>
  3. <dt>{item.key}</dt>
  4. <dd>{item.value}</dd>
  5. </template>
  6. </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.

  1. <loop>
  2. <ul>
  3. <li each={ user in users } key={ user.id }>{ user.name }</li>
  4. </ul>
  5. <script>
  6. export default {
  7. users: [
  8. { name: 'Gian', id: 0 },
  9. { name: 'Dan', id: 1 },
  10. { name: 'Teo', id: 2 }
  11. ]
  12. }
  13. </script>
  14. </loop>

The key attribute can be also generated in runtime via expressions

  1. <loop>
  2. <ul>
  3. <li each={ user in users } key={ user.id() }>{ user.name }</li>
  4. </ul>
  5. <script>
  6. export default {
  7. users: [
  8. { name: 'Gian', id() { return 0 } },
  9. { name: 'Dan', id() { return 1 } },
  10. { name: 'Teo', id() { return 2 } }
  11. ]
  12. }
  13. </script>
  14. </loop>