vue中列表渲染有key与没有key的区别

当 Vue 使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。
这句话是什么意思呢,看一下图你就会理解:


数据由[A,B,C,D]改变成了[A,E,C,D]的过程。
数据由[A,B,C,D]改变成了[E,A,B,C,D]的过程。

这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。
为什么这么说呢,运行一下以下代码你就会发现问题:

  <div>
    <input type="text" v-model="name">
    <button @click="add">添加</button>
  </div>
  <div v-for="name in list">
    <input :id="name" type="radio" name="name" :value="name" v-model="checkedNames">
    <label :for="name">{{name}}</label>
  </div>
  <div>Checked names: {{ checkedNames }}</div>
data() {
    return {
        name: '',
        list: ['张三', '李四', '王五'],
        checkedNames: []
      }
},
methods: {
   add() {
      this.list.unshift(this.name);
   }
 }
先选中“张三”
添加“十一”

从上面我们发现,开始选中的张三,当添加一个十一后,虽然选中的值显示张三,但页面展示却选中了十一,这显然是错误的,这就是就地更新造成的错误。
当我们给代码加上key时,问题就解决了(添加时保证name的唯一性)。

<div>
    <input type="text" v-model="name">
    <button @click="add">添加</button>
  </div>
  <div v-for="name in list" :key="name">
    <input :id="name" type="radio" name="name" :value="name" v-model="checkedNames">
    <label :for="name">{{name}}</label>
  </div>
  <div>Checked names: {{ checkedNames }}</div>
image.png

key的作用主要用在 Vue 的虚拟 DOM 算法,给 Vue 一个提示,以便能跟踪每个节点的身份,从而重用和重新排序现有元素,移除 key 不存在的元素(并且根据源码可以看出,在比较新老节点首尾节点交叉进行sameVnode比对都不相同时,有key后续的比对会更快,通过map可以快速定位,不需要去遍历老节点sameVnode寻找)。

数据由[A,B,C,D]改变成了[E,A,B,C,D]的过程。
数据由[A,B,C,D]改变成了[A,E,C,D]的过程。

如有不正确的地方,欢迎指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 6 条件渲染 v-if 指令用于条件性地渲染一块内容。这块内容只会在指令的表达式返回 truthy 值的时候被渲染...
    刘惜雨阅读 852评论 0 0
  • 条件渲染 v-if 在<template>元素上使用v-if条件渲染分组 最终的渲染结果将不包含<template...
    oWSQo阅读 834评论 1 0
  • 1.用 v-for 把一个数组对应为一组元素 我们用 v-for 指令根据一组数组的选项列表进行渲染。v-for ...
    Sunshinga阅读 258评论 0 0
  • 用 v-for 把一个数组 对应为 一组元素 我们使用 v-for 指令根据数组的列表来进行渲染。v-for指令需...
    XKolento阅读 710评论 0 12
  • 列表循环 v-for 将一个数组对应为一组元素 v-for指令根据数组选项列表进行渲染,使用时需使用item in...
    JunChow520阅读 3,375评论 0 1

友情链接更多精彩内容