• 2/2 从一个简单例子来看 Vue.js 中 v-for 中 key 值的重要性


    写在前面

      最近把基础都看了一下,在弄过渡的时候,将之前的知识串了起来,由此做了一篇小随笔

      在我的学习过程中,每每听到v-for视频里面的老师都说要加一个key值,有些时候不加其实也一样,为什么key这么重要呢?

      我来通过我的经验半吊子回答一下

    1.就近复用

      就近复用,其实就是当用v-for的时,没有给定key值会发生的情况

      例如,我要通过 v-for 打印一个数组出来

      

      elements

    ·  

      那么这里面的每一个 < li > 标签 看似 是和 数组里面的数据 ” 一一对应 “了

      但是其实不是,因为没有 key 值 DOM和元素没有一一映射, 当数据发生改变时,Vue 是采取

        就近复用 来重新渲染的 DOM ( 没有 key 的情况下,一般来说 输出没有什么大变化 )

      

        key值是为了建立 值和 DOM节点的 映射关系 而方便进一步操作的 一个标志

      


      可能到这里还是会对 key 不是很清楚, 这里有一个 过渡 例子

     

     

    2.过渡的 v-move

      

      1 <!DOCTYPE html>
      2 <html>
      3 
      4 <head>
      5   <title> </title>
      6 </head>
      7 
      8 <body>
      9   <style>
     10     .list-enter,
     11     .list-leave-to {
     12       opacity: 0;
     13     }
     14 
     15     .list-enter-active {
     16       animation: moveIn 1s;
     17     }
     18 
     19     .list-leave-active {
     20       animation: moveOut 1s;
     21       /* transition: all 1s linear; */
     22     }
     23 
     24     @keyframes moveIn {
     25       0% {
     26         opacity: 0;
     27         transform: translate(30px, 15px);
     28       }
     29 
     30       30% {
     31         opacity: 0.5;
     32         transform: translate(0px, 15px);
     33       }
     34 
     35       100% {
     36         opacity: 1;
     37         transform: translate(0, 0px);
     38       }
     39     }
     40 
     41     @keyframes moveOut {
     42       0% {
     43         opacity: 1;
     44         transform: translate(0, 0px);
     45       }
     46 
     47       30% {
     48         opacity: 0.5;
     49         transform: translate(0px, 15px);
     50       }
     51 
     52       100% {
     53         opacity: 0;
     54         transform: translate(30px, 15px);
     55       }
     56     }
     57 
     58     /* 重新随机排序用的是 move */
     59     .list-move {
     60       transition: all 1s;
     61     }
     62   </style>
     63   <div id="app">
     64     <button @click="addNewItem()">添加元素</button>
     65     <button @click="delNewItem()">删除元素</button>
     66     <button @click="orderByRandom()">随机排序</button>
     67     <br>
     68     <!-- tag 必须指定某个标签 而且里面的标签也必须要有KEY值 -->
     69     <transition-group name="list" tag="ul">
     70       <!-- <li v-for="item in list" :key="list.indexOf(item)"> -->
     71       <!-- 上面这样定义key值的话,就不会出现随机排序的动画效果 -->
     72       <li v-for="item in list" :key="item">
     73         {{ item }}
     74       </li>
     75     </transition-group>
     76   </div>
     77   <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
     78   <script type="text/javascript">
     79     // 声明 Vue 实例
     80     let vm = new Vue({
     81       el: '#app',
     82       data() {
     83         return {
     84           list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
     85         }
     86       },
     87       methods: {
     88         addNewItem() {
     89           this.list.push(this.list.length)
     90         },
     91         delNewItem() {
     92           this.list.pop()
     93         },
     94         orderByRandom() { // 随机改变数组元素的位置
     95           let tmp = [] // 初始化新数组
     96           for (let i = 0; i < this.list.length; i++) {
     97             let num = Math.floor(Math.random() * (this.list.length - 0.001)) // 随机新元素
     98             // 当元素不在数组中时,将其加入到数组中
     99             let index = tmp.indexOf(num)
    100             while (index !== -1) {
    101               num = Math.floor(Math.random() * (this.list.length - 0.001))
    102               index = tmp.indexOf(num)
    103             }
    104             tmp.push(num)
    105           }
    106           this.list = tmp // 更改list为新的数组
    107         }
    108       }
    109     })
    110   </script>
    111 </body>
    112 
    113 </html>

     

      因为 transition-group 必须加 key , 这里就小技巧一下,70-71行

        <li v-for="item in list" :key="list.indexOf(item)">

      通过对赋值 key 为每一个元素的位置信息,当位置信息不改变时,就不会发生move动画

      可以f12调试一下

      因为 key 相当于一个身份信息,当这个身份信息没有发生改变的时候( list.indexOf(item) ),就不会发生move, 进行的只是数值的改变

        又因为,每一次的增加,减少 是对于位置的增加,减少,相应的 DOM也会如此,所以有过渡动画

      可见,key值的重要性 从根本上来说,是让 Vue 能够有迹可循追踪数据到相应的节点

      

     总结

      感冒了,好难受

     

     

      凭着意念弄了出来,继续加油

     

     

      

     

      ps: 敲代码是尤其重要的,看不出来别人的问题,只有自己实践了才会出现好多问题

    Let it roll
  • 相关阅读:
    Java基本数据类型
    Java位运算符
    Java条件编译
    Groovy学习笔记(二)
    Groovy学习笔记(一)
    Java开发环境搭建
    Java接口回调
    [精华][推荐]CAS SSO单点登录服务端客户端实例
    CAS SSO单点登录实例
    分布式架构springcloud+redis+springmvc+springboot
  • 原文地址:https://www.cnblogs.com/WaterMealone/p/14363184.html
Copyright © 2020-2023  润新知