添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Vue 组件是由管理应用程序数据的 JavaScript 对象和映射到基础 DOM 结构的基于 HTML 的模板语法组成的。为了进行安装并使用 Vue 的一些更高级的功能(例如“单文件组件(SFC)”或渲染功能),你将需要一个装有 node + npm 的终端。

利用 v-for 指令渲染列表

一个有效的待办事项列表需要有多个被渲染的 to-do 项,Vue 中的 v-for 可以用来实现这种效果。它是 Vue 自带的指令,用于在 template 中实现循环,我们可以利用它将数组中的各项重复渲染成指定的特征。我们将利用它迭代待办事项列表,将其中的每一项展示为单独的 ToDoItem 组件。

添加一些需要渲染的数据

首先我们需要准备一个待办事项数组。添加 data 属性到 App.vue 组件对象中,它包含一个 ToDoItems 字段,其值是待办事项数组。在最终完成添加新的待办事项功能之前,我们可以先 mock 一些待办项目,每个待办项目可以用一个对象表示,这个对象含有 label done 属性。

像下面这样添加一些待办项目让我们可以利用 v-for 来对它们进行渲染。

js
export default {
  name: "app",
  components: {
    ToDoItem,
  data() {
    return {
      ToDoItems: [
        { label: "Learn Vue", done: false },
        { label: "Create a Vue project with the CLI", done: true },
        { label: "Have fun", done: true },
        { label: "Create a to-do list", done: false },

现在我们有了一个列表,可以用 v-for 去展示它们了。指令的作用方式和元素的属性类似,就 v-for 而言,它类似 JavaScript 中的 for...in 循环——v-for="item in items"——items 是你要迭代的列表,item 是数组中当前元素的引用。

v-for 获取每个迭代的元素,并渲染它和它的子元素。在我们的例子中,我们用 <li> 的形式展示每一个待办事项,接下来我们会通过每个待办事项传递数据到其对应的 ToDoItem 组件。

Key 属性

在进行数据传递之前,我们要了解下 key 属性,它和 v-for 一起使用,用来帮助 Vue 标识列表中的元素,这样 Vue 就不需要在列表变化时重新创建它们。为了确保它适当地重新使用列表元素,它需要在你附加 v-for 的同一个元素上有一个独特的“key”。

为了确保 Vue 能够准确地比较 key 属性,它们需要是字符串或数字值。虽然使用名字字段很好,但这个字段最终将由用户输入控制,这意味着我们不能保证名字是唯一的。然而,我们可以使用 lodash.uniqueid() ,就像我们在上一篇文章中做的那样。

使用导入 ToDoItem 组件相同的方法导入 nanoid App 组件。

js
import { nanoid } from "nanoid";

添加 id 字段到 ToDoItems 数组的每一个元素中,并且将他们赋值为 uniqueId('todo-')

此时,App.vue 中的 <script> 元素内容应该如下:

js
import ToDoItem from "./components/ToDoItem.vue";
import { nanoid } from "nanoid";
export default {
  name: "app",
  components: {
    ToDoItem,
  data() {
    return {
      ToDoItems: [
        { id: "todo-" + nanoid(), label: "Learn Vue", done: false },
          id: "todo-" + nanoid(),
          label: "Create a Vue project with the CLI",
          done: true,
        { id: "todo-" + nanoid(), label: "Have fun", done: true },
          id: "todo-" + nanoid(),
          label: "Create a to-do list",
          done: false,

在你的 App.vue 模板中添加 v-for 指令和 key 属性到 <li> 元素:

html
<ul>
  <li v-for="item in ToDoItems" :key="item.id">
    <to-do-item label="My ToDo Item" :done="true"></to-do-item>

这样修改后,<li> 标签中的 JavaScript 表达式就可以访问 item 了,这意味着我们可以使用 v-bind 来传递 item 对象的字段给 ToDoItem 组件了。这非常有用,我们想让列表中的待办事项的 label 值展示到它的 label 中,而不是显示一个静态的“My Todo Item”。此外,我们想让它们的 checked 状态反映它们的 done 字段,而不是总设置为 done="true"

label="My ToDo Item" 改成 :label="item.label":done="false" 改成 :done="item.done",像下面这样:

html
<ul>
  <li v-for="item in ToDoItems" :key="item.id">
    <to-do-item :label="item.label" :done="item.done"></to-do-item>

现在当你去看运行着的 app 时,你会发现待办事项显示了它们自己正确的名字,如果你查看源码的话,你会发现输入都有了唯一的 id,它取自 App 组件中的对象。

含有已渲染的待办事项的应用

让我们来一点小重构

在这里我们可以做一个小小的重构。我们可以把 id 变成一个 prop,而不是在 ToDoItem 组件中为复选框生成它。虽然这不是严格意义上的需要,但它使我们更容易管理,因为我们已经需要为每个 todo 项目创建一个唯一的 id

  • 添加一个新的 prop id ToDoItem 组件。
  • 标记它为 required,类型是 String
  • 为防止命名冲突,删除掉 data 属性中的 id 字段。
  • 现在不需要再使用 nanoid 了,所以需要删除掉 import { nanoid } from 'nanoid'; 这行,否则你的应用会报错。
  • 现在, ToDoItem 中的 <script> 内容应该如下所示:

    js
    export default {
      props: {
        label: { required: true, type: String },
        done: { default: false, type: Boolean },
        id: { required: true, type: String },
      data() {
        return {
          isDone: this.done,
    

    现在,在 App.vue 组件中将 item.id 作为 prop 传递给 ToDoItem 组件。你的 App.vue template 应该如下所示:

    html
    <template>
      <div id="app">
        <h1>My To-Do List</h1>
          <li v-for="item in ToDoItems" :key="item.id">
            <to-do-item
              :label="item.label"
              :done="item.done"
              :id="item.id"></to-do-item>