Grouping with <template>

Sometimes a v-if or a v-for should cover several elements at once. You could wrap them in a div, but that isn't always allowed (a ul may only have lis inside it) or wanted (it can upset a layout). Put the directive on a <template> element instead. It groups the elements inside it, and Vue doesn't put the <template> itself on the page:

<template v-if="open">
    <h2>Menu</h2>
    <p>Fresh coffee and cake every day.</p>
</template>
<p v-else>Sorry, we're closed.</p>

While open is true, the page gets just the h2 and the p, with nothing around them. <template v-for> works the same way, with the :key on the <template>:

<template v-for="item in menu" :key="item.id">
    <h3>{{ item.name }}</h3>
    <p>€{{ item.price }}</p>
</template>

And here's something you should never do: put v-if and v-for on the same element, say to show only the items that aren't sold out:

<li v-for="item in menu" v-if="!item.soldOut" :key="item.id">{{ item.name }}</li>

Vue checks v-if first, before v-for has made item, so in the condition, item doesn't exist yet. The page stays empty, and the console starts with this warning:

[Vue warn]: Property "item" was accessed during render but is not defined on instance.
  at <App>

A few lines later comes the error TypeError: Cannot read properties of undefined (reading 'soldOut').

Put the v-for on a <template> around the element instead, and leave the v-if on the element:

<template v-for="item in menu" :key="item.id">
    <li v-if="!item.soldOut">{{ item.name }}</li>
</template>

Typical mistake: :key on the element inside <template v-for>. The page doesn't run, and the red bar says <template v-for> key should be placed on the <template> tag.

Instructions

  1. Show only the items that aren't sold out: put the v-for on a <template> around the li, and give the li a v-if.

  2. When the café is closed, hide the heading and the list, and show <p class="closed">Sorry, we're closed.</p> instead. Group the heading and the list with <template v-if>, so that the page has no element around them.