在组件上使用 v-for

这部分内容假定你已经了解组件相关知识。你也完全可以先跳过它,以后再回来查看。

在自定义组件上,你可以像在任何普通元素上一样使用 v-for

  1. <my-component v-for="item in items" :key="item.id"></my-component>

2.2.0+ 的版本里,当在组件上使用 v-for 时,key 现在是必须的。

然而,任何数据都不会被自动传递到组件里,因为组件有自己独立的作用域。为了把迭代数据传递到组件里,我们要使用 prop:

  1. <my-component
  2. v-for="(item, index) in items"
  3. v-bind:item="item"
  4. v-bind:index="index"
  5. v-bind:key="item.id"
  6. ></my-component>

不自动将 item 注入到组件里的原因是,这会使得组件与 v-for 的运作紧密耦合。明确组件数据的来源能够使组件在其他场合重复使用。

下面是一个简单的 todo 列表的完整例子:

  1. <div id="todo-list-example">
  2. <form v-on:submit.prevent="addNewTodo">
  3. <label for="new-todo">Add a todo</label>
  4. <input
  5. v-model="newTodoText"
  6. id="new-todo"
  7. placeholder="E.g. Feed the cat"
  8. >
  9. <button>Add</button>
  10. </form>
  11. <ul>
  12. <li
  13. is="todo-item"
  14. v-for="(todo, index) in todos"
  15. v-bind:key="todo.id"
  16. v-bind:title="todo.title"
  17. v-on:remove="todos.splice(index, 1)"
  18. ></li>
  19. </ul>
  20. </div>

注意这里的 is="todo-item" 属性。这种做法在使用 DOM 模板时是十分必要的,因为在 <ul> 元素内只有 <li> 元素会被看作有效内容。这样做实现的效果与 <todo-item> 相同,但是可以避开一些潜在的浏览器解析错误。查看 DOM 模板解析说明 来了解更多信息。

  1. Vue.component('todo-item', {
  2. template: '\
  3. <li>\
  4. {{ title }}\
  5. <button v-on:click="$emit(\'remove\')">Remove</button>\
  6. </li>\
  7. ',
  8. props: ['title']
  9. })
  10. new Vue({
  11. el: '#todo-list-example',
  12. data: {
  13. newTodoText: '',
  14. todos: [
  15. {
  16. id: 1,
  17. title: 'Do the dishes',
  18. },
  19. {
  20. id: 2,
  21. title: 'Take out the trash',
  22. },
  23. {
  24. id: 3,
  25. title: 'Mow the lawn'
  26. }
  27. ],
  28. nextTodoId: 4
  29. },
  30. methods: {
  31. addNewTodo: function () {
  32. this.todos.push({
  33. id: this.nextTodoId++,
  34. title: this.newTodoText
  35. })
  36. this.newTodoText = ''
  37. }
  38. }
  39. })

在组件上使用 v-for - 图1