Skip to content

列表渲染

1.v-for指令

作用:用于遍历可迭代对象显示列表

可遍历数组、对象、字符串、数字(用的少)、指定次数(用的少)

语法:这里key可以是index,但最好是绑定一个唯一标识,比如id

1.1 遍历数组

v-for 指令需要使用 item in items 形式的特殊语法来遍历数组

  • 其中 items 是源数据数组
  • item 则是当前迭代元素

假如有一个数组dataSource:['张三','李四','王五']

vue
<li v-for="item of dataSource" :key="item"> {{item}} </li>

结果会是如下这样

image-20250811105805634

遍历数组时,可以添加第二个参数index,即当前遍历元素的索引,注意多个参数时,要把参数放进()

vue
<li v-for="(item, index) of dataSource" :key="item"> {{item}},{{index}} </li>

image-20250811110038619

若数组里是一个个对象,那么就可以使用item.key访问当前遍历对象中的数据,而key一般是需要一个唯一的数据值,一般都是id

vue
<template>
  <div>
    <li v-for="(item, index) of dataSource" :key="item.id">
      序号:{{ index + 1 }},姓名:{{ item.name }}
    </li>
  </div>
</template>

<script>
export default {
  data() {
    return {
      dataSource: [
        { name: "张三", id: 1 },
        { name: "李四", id: 2 },
        { name: "王五", id: 3 },
      ],
    };
  },
};
</script>

1.2 遍历对象

当v-for遍历对象时:

  • 第一个参数为当前键的值
  • 第二个参数为键名
  • 第三个参数为当前索引
vue
<template>
  <div>
    <li v-for="(value, key, index) in obj" :key="index">
      值:{{ value }} ,键:{{ key }} ,索引:{{ index }}
    </li>
  </div>
</template>

<script>
export default {
  data() {
    return {
      obj: {
        name: "坤坤",
        age: 18,
        time: 2018,
      },
    };
  },
};
</script>

image-20250811110950136

TIP

在遍历对象时,会按 Object.keys() 的结果遍历,但是不能保证它的结果在不同的 JavaScript 引擎下都一致。

1.3 遍历整数

v-for 也可以接受整数。在这种情况下,它会把模板重复对应次数。

<div>
  <span v-for="n in 10">{{ n }} </span>
</div>

结果:

txt
1 2 3 4 5 6 7 8 9 10

1.4 在template上使用 v-for

类似于 v-if,你也可以利用带有 v-for<template> 来循环渲染一段包含多个元素的内容。比如:

vue
<ul>
  <template v-for="item in items">
    <li>{{ item.msg }}</li>
    <li class="divider" role="presentation"></li>
  </template>
</ul>

1.v-for 与 v-if 一同使用

TIP

注意我们推荐在同一元素上使用 v-ifv-for

当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。当你只想为部分项渲染节点时,这种优先级的机制会十分有用,如下:

vue
<li v-for="todo in todos" v-if="!todo.isComplete">
  {{ todo }}
</li>

上面的代码将只渲染未完成的 todo。

而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或 [`) 上。如:

vue
<ul v-if="todos.length">
  <li v-for="todo in todos">
    {{ todo }}
  </li>
</ul>
<p v-else>No todos left!</p>

注意

在vue2和vue3中,v-for和v-if的优先级有所不同

  • vue2中:v-for 具有比 v-if 更高的优先级
  • vue3中:v-ifv-for 的优先级更高

image-20250811112233104

image-20250811112252508

2.key

使用v-for指令时,遍历的每一项都需要有一个key属性,而且必须是唯一值

作用:key是虚拟DOM中对象的标识,当数据发生变化时,Vue会根据新数据生成新的虚拟DOM,随后Vue进行新虚拟DOM与旧虚拟DOM的差异比较,比较规则如下

2.对比规则

  • 旧虚拟DOM中找到了与新虚拟DOM相同的key

    • 若虚拟DOM中内容没变, 直接使用之前的真实DOM

    • 若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM

  • 旧虚拟DOM中未找到与新虚拟DOM相同的key创建新的真实DOM,随后渲染到到页面

index作为key可能会引发的问题

  • 若对数据进行逆序添加逆序删除等破坏顺序操作,会产生没有必要的真实DOM更新 ==> 界面效果没问题,但效率低

  • 若结构中还包含输入类的DOM:会产生错误DOM更新 ==> 界面有问题

开发中如何选择key?

最好使用每条数据的唯一标识作为key,比如 id、手机号、身份证号、学号等唯一值

如果不存在对数据的逆序添加、逆序删除等破坏顺序的操作,仅用于渲染列表,使用index作为key是没有问题的

2.1 虚拟dom

2.2 diff算法

MIT Licensed