本文会带着大家过一遍Vue中的key有什么作用,以及key的值为什么不可以用index

我们时候会用到key

相信大家在最开始学习Vue的时候,大概是在学习v-for这个指令的时候接触到key的,我用代码带着大家复现一遍

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./vue.js"></script>
</head>

<body>
  <div id="root">
    <button @click="add">添加一个老刘</button>
    <hr>
    <ul>
      <li v-for="(p,index) of persons">
        {{ p.name }}-{{ p.age }}
        <input type="text">
      </li>
    </ul>
  </div>
  <script>
    Vue.config.productionTip = false

    new Vue({
      el: '#root',
      data: {
        persons: [
          { id: 1, name: '张三', age: 18 },
          { id: 2, name: '李四', age: 19 },
          { id: 3, name: '王五', age: 20 },
        ]
      },
      methods: {
        add() {
          const p = { id: 4, name: '老刘', age: 21 }
          this.persons.unshift(p)
        }
      },
    })
  </script>
</body>

</html>

在这里插入图片描述

按照以上代码,我们得到了浏览器所显示的内容,但是在这里,大家会发现,我并没有加key这个属性,这是因为:

如果不添加key属性,则系统默认给我们加了一个key,而且它的默认值是index

也就是说

<li v-for="(p,index) of persons">

等于

<li v-for="(p,index) of persons" :key="index">

这点我就说到这里了

好,我们现在知道了key在什么时候出现,啊,是在列表渲染的时候出现
但是我们还是不知道这个key到底是干什么的

虚拟DOM

我们在知道key的作用之前,首先要知道Vue的一个特性

使用虚拟DOM和Diff算法,尽量复用DOM节点

我不知道大家到底清不清楚这个虚拟DOM(VDOM)是什么,这里我简单带着大家复习一下

我们先要知道,我们在原生JS里面去写一个人员列表的时候,我们是怎么写的
在这里插入图片描述
我们是这样去写的,但是我们发没发现一个问题,如果我们想在这个列表里面添加一个新的数据呢,我们需要遍历一遍,看看有没有相同的元素,然后再插进去,是不是挺麻烦的

于是,在Vue中,我们有了一个新的概念,虚拟DOM
在这里插入图片描述
我们第一遍添加数据的时候,Vue会把我们添加数据放入到一个虚拟DOM中,然后在我们添加新的数据的时候,会产生新的虚拟DOM,关键来了
我们新的虚拟DOM会和旧的虚拟DOM进行一个比较,看看有没有什么不同(different)简称Diff算法发现新的虚拟DOM中有跟旧虚拟DOM中有相同的内容,那么,我们就会直接调用旧的虚拟DOM中的内容(也就是复用),从而提高效率

好了,这个就带着大家复习到这里,我们还是进入正题

key的作用

我们新虚拟DOM在跟旧的虚拟DOM进行对比的时候,是根据key值的序号,逐个进行对比的

在这里插入图片描述
key为1的新虚拟DOM去找key为1的旧的虚拟DOM,看看内容是不是一样,如果一样,就直接复用,如果不一样,就修改为新的内容,或者添加新的内容
不知道大家有没有懂,这里带着大家用个常见的反例,带着大家感受一下,就是为什么不能用index(索引值)用来当作key值

index做key值为什么不行

在这里插入图片描述
我们直接点击按钮,添加,ok,没有看出什么问题
但是,如果初始的文本框里是有内容的呢?
在这里插入图片描述

我们再点击添加按钮试试

在这里插入图片描述
发现问题了吗,是不是串了

这是为什么呢?
我们就拿张三举例,它最开始的索引值是不是0,但是在头部添加了一个新的元素之后,它的索引值是不是就变成1了,依次,是不是原本的内容,索引值都变化了,这就导致了一个关键的问题,key值变了
在这里插入图片描述
然后我们虚拟DOM还是根据key值进行diff算法的,是不是这下就完犊子了,全变了,不能怪我VDOM瞎,是这index太完蛋,它变啥

这样,是不是我们就知道为什么不能用index值来当作key值了

因为index的值是变化的

这样也引出了一个重要的概念,我们的key值,需要一个固定不变的值,就类似于我们的身份证号一样,需要值与元素一一对应,要唯一

当然哈,有的小伙伴会问,那为啥是id呢,不可以是别的呢

这随意啊!只要是固定的值,就可以,只不过我们习惯于id了,我们在数据链接MySQL的值,一般后端都会自动给我们生成,都是做好了的,他给我们什么名字,我们就用什么名字,给的名字为id,我们就用id,给我们hhh,我们就要hhh

总结

面试题:react、vue中的key有什么作用?(key的内部原理)

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

  2. 对比规则:
    (1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
    ①.若虚拟DOM中内容没变, 直接使用之前的真实DOM!
    ②.若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
    (2).旧虚拟DOM中未找到与新虚拟DOM相同的key
    创建新的真实DOM,随后渲染到到页面。

  3. 用index作为key可能会引发的问题:
    1.若对数据进行:逆序添加、逆序删除等破坏顺序操作:
    会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。

  4. 如果结构中还包含输入类的DOM:
    会产生错误DOM更新 ==> 界面有问题。

  5. 开发中如何选择key?:
    1.最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
    2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,
    使用index作为key是没有问题的。

OK,结束了,感谢观看,有问题就问

Logo

前往低代码交流专区

更多推荐