目录
v-for参数
首先我先粗略的讲v-for遍历时的参数进行一个说明:
例如:在vue的data中定义一个数组对象:
data: { persons:[ {id:'001',name:'张三',age:18}, {id:'002',name:'李四',age:19}, {id:'003',name:'王五',age:20}, ] }
然后我们对其进行遍历:
<ul> <li v-for="(a,b,c) in persons"> {{a}}--{{b}}--{{c}} </li> </ul>
得到的结果如下图:
由此可知v-for在遍历数组时可以得到两个参数。分别是值和索引 。当然v-for还可以遍历对象,字符串等(其它遍历产生的参数就不在这里详细说明了,我们主要说一下key值会产生的问题)。
key值 :
那我们先来说一下使用indexx作为key值会产生哪些问题吧:
我们先设计一个简单的表单:点击按钮可以在列表最上面添加一个新的对象
const v=new Vue({ el: "#root", data: { persons:[ {id:'001',name:'张三',age:18}, {id:'002',name:'李四',age:19}, {id:'003',name:'王五',age:20}, ] }, methods: { add(){ const p={id:'004',name:'雪球',age:20} this.persons.unshift(p) } }, })
html中使用index作为v-for遍历时的key的值
<div id="root"> <button @click="add">添加一个雪球</button> <ul> <li v-for='p in persons' :key="index"> {{p.name}}-{{p.age}} <input type="text"> </li> </ul>
此时点击按钮产生的结果如下图:
接下来我开始演示一下存在的问题,首先我把对应的数据写在他们各自对应的输入框中
,如下图:
当我们点击按钮时期望出现的效果是:
可实际上当:key=“index”时出现的效果为:
接下来对上面产生的问题进行一个解释:
index作为key
现在我对上面图示进行一个解释:
1.在遍历初始数据时根据key给每个遍历的数据产生一个key值(如果使用key这个关键字的话,key值在真实DOM中并不显示出来,vue将它隐藏了)。在上述例子中我们选择了用索引值index作为key的值。
2.因此产生了key值为索引的一个虚拟DOM,紧接着将虚拟DOM转换为真实DOM。
3.当我们点击按钮时,他会产生一个新的数据,新数据同样会生成一个key值为索引的虚拟DOM,如上图,vue会将新产生的虚拟DOM和之前的虚拟DOM进行对比,上图中首先对比key值发现key值相同,然后对比文字内容,发现文字内容不同,于是将原来的‘张三-18’替换为老刘-30’,紧接着对比input输入框,发现一样,因此直接采用复用(这里可能会有人提出质疑:“input输入框也不一样啊,我们刚才在输入框中输入了内容”,但其实并不是这样,我们在输入框中输入的内容属于在真实DOM中的操作,但是现在进行对比的是新生成的虚拟DOM和原来的虚拟DOM进行对比,输入框中都没有内容,他们的输入框是一样的)。将输入框采取复用后,开始进行下一个数据的对比,同样的道理,依次对比,在进行到王五时发现此时key='3',没有key值与之相同,因此只能直接新生成一条真实数据。
4.综上所述,就产生了我们说的那种错误的效果,这就是利用key="index"产生的问题。
为了避免这种情况的出现:我们往往使用唯一标识符作为key的值,例如:手机号,id等。
加深一下大家的印象,对唯一标识符我也通过图片稍加解释一下:
id作为key
在将新数据生成的虚拟DOM和原数据生成的虚拟DOM进行对比时,原数据的虚拟DOM中没有key为004的数据,因此直接新生成一个真实DOM,接着对比key="001",发现有相同的key,于是进行文字输入框对比,发现一样,在直接采用复用。依次进行对比。最终产生的效果就是正常情况。
总结:
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更新==>界面效果没问题,但效率低。
2.如果结构中还包含输入类的DOM:
会产生错误DOM更新==>界面有问题。
开发中如何选择key?
1.最好使用每条数据的唯一标识作为key,比如id、手机号、身份证号、学号等唯一值。
2.如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,
使用index作为key是没有问题的。