When they exist on the same node,
v-for
has a higher priority than
v-if
. That means the
v-if
will be run on each iteration of the loop separately. This can be useful when you want to render nodes for only
some
items, like below:
<liv-for="todo in todos"v-if="!todo.isComplete"> {{ todo }} </li>
The above only renders the todos that are not complete.
If instead, your intent is to conditionally skip execution of the loop, you can place the
v-if
on a wrapper element (or
<template>
). For example:
<ulv-if="todos.length"> <liv-for="todo in todos"> {{ todo }} </li> </ul> <pv-else>No todos left!</p>
You can directly use
v-for
on a custom component, like any normal element:
<my-componentv-for="item in items":key="item.id"></my-component>
In 2.2.0+, when using
v-for
with a component, a
key
is now required.
However, this won’t automatically pass any data to the component, because components have isolated scopes of their own. In order to pass the iterated data into the component, we should also use props:
<my-component v-for="(item, index) in items" v-bind:item="item" v-bind:index="index" v-bind:key="item.id" ></my-component>
The reason for not automatically injecting
item
into the component is because that makes the component tightly coupled to how
v-for
works. Being explicit about where its data comes from makes the component reusable in other situations.
Here’s a complete example of a simple todo list:
<divid="todo-list-example"> <formv-on:submit.prevent="addNewTodo"> <labelfor="new-todo">Add a todo</label> <input v-model="newTodoText" id="new-todo" placeholder="E.g. Feed the cat" > <button>Add</button> </form> <ul> <li is="todo-item" v-for="(todo, index) in todos" v-bind:key="todo.id" v-bind:title="todo.title" v-on:remove="todos.splice(index, 1)" ></li> </ul> </div>
Note the
is="todo-item"
attribute. This is necessary in DOM templates, because only an
<li>
element is valid inside a
<ul>
. It does the same thing as
<todo-item>
, but works around a potential browser parsing error. See
DOM Template Parsing Caveats
to learn more.