前言
v-for:列表渲染
一、v-for
v-for将JSON数据中的数组或对象渲染出列表的样式呈现。
直接见代码实例,如下:
<!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 type="text/javascript" src="../js/vue.js"></script> </head> <body> <div id="root"> <h2>遍历数组</h2> <ul> <li v-for="(p,index) in person"> {{p.id}}--{{p.name}} </li> </ul> <h2>遍历对象</h2> <ul> <li v-for="(value,key) in car"> {{key}}--{{value}} </li> </ul> <h2>遍历字符串</h2> <ul> <li v-for="(char,index) in str"> {{char}}--{{index}} </li> </ul> <h2>遍历次数</h2> <ul> <li v-for="(number,index) in 5"> {{number}}--{{index}} </li> </ul> </div> <script> var vm = new Vue({ el: "#root", data: { person: [{ id: "001", name: "张三" }, { id: "002", name: "李四" }, { id: "003", name: "王五" }], car: { name: "马自达", price: "¥3000000" }, str: "hello" } }) </script> </body> </html>
二、key
1.介绍
- key的作用主要是为了高效的更新虛拟DOM,其原理是vue在patch(补丁)过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,使得整个patch过程更加高效,减少DOM操作量,提高性能。
- 另外,若不设置key还可能在列表更新时引发一些隐蔽的bug。如某行数据不该更新的却更新了。
- vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。
2.使用
格式:<标签 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 type="text/javascript" src="../js/vue.js"></script> </head> <body> <div id="root"> <button @click="add">点我添加老刘</button> <ul> <li v-for="(p,index) in person" :key="index"> {{p.name}}--{{p.age}} <input type="text"> </li> </ul> </div> <script> var vm = new Vue({ el: "#root", data: { person: [{ id: "001", name: "张三", age: 18 }, { id: "002", name: "李四", age: 19 }, { id: "003", name: "王五", age: 20 }] }, methods: { add() { const p = { id: "004", name: "老刘", age: 40 } this.person.unshift(p) } } }) </script> </body> </html>
现在我们在页面上的文本框中添加对应信息,如下:
然后点击按钮,如下:
我们可以观察到老刘的文本框对应的是张三,张三对应的的文本框是李四,李四的文本框对应的是王五,王五空了,这是为什么吗呢,继续看下面!
3.原理
结合下面图片进行讲解:
上诉代码中key的值是与数组下标绑定的,添加老刘用的是unshift方法(将新的元素添加到数组最前面),所以老刘是第一个元素,key是0,其他依次。没有添加老刘前(图片左边),添加老刘后虚拟DOM改变(图片右边),在添加老刘后key发生变化,Vue内部的对比算法依据key值与原来的虚拟DOM比较(即key相同的进行比较),看下面图片,比较key=0的DOM对象,标签内文本不一样所以用更新后的,input,li标签一样继续沿用以前的,因此这就是上诉情况的原因:Vue的对比算法,对比的是虚拟DOM,而我们文本框填入对应信息是在真是DOM的操作,所以对比算法无法判断input内文本的改变,只知道input没改变,所以继续沿用的未添加前的key=0的li标签内的input。发生上述情况其实就是数组元素下标改变,key值对应发生变化,后面的都是这个原理。
当我们key与数组下标绑定时,要想不发生上诉情况,可以将老刘的添加用push方法(将元素添加到数组的最后),这样在添加后,原来的DOM对象key值没发生变化,按照数组下标。其实最好的方法是将key与上诉唯一标识id绑定,这样就可以忽略数组添加新元素的方法
4.总结
- 虚拟DOM中的key的作用:
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】,随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较。 - 对比规则:
(1)旧虚拟DOM中找到了与新虚拟DOM相同的key:
若虚拟DOM中内容没变,直接使用之前的真实DOM!
若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM
(2)旧虚拟DOM中未找到与新虚拟DOM相同的key:
创建新的真实DOM随后渲染到页面 - 用index作为key可能引发的问题:
(1)若对数据进行:逆序添加、逆序删除等破坏顺序的操作:
会产生没有必要的真实DOM更新==>界面效果没问题,但效率低
(2)如果结构中还包含输入类的DOM:
会产生错误DOM更新==>界面有问题 - 开发中如何选择key:
(1)最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值
(2)如果不存在对数据的逆序添加、逆序删除等破坏顺序的操作,仅用于渲染列表用于展示,使用index作为key是没有问题的
总结
以上就是v-for和key的讲解。