写在前面
最近把基础都看了一下,在弄过渡的时候,将之前的知识串了起来,由此做了一篇小随笔
在我的学习过程中,每每听到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: 敲代码是尤其重要的,看不出来别人的问题,只有自己实践了才会出现好多问题