文章目录
- 基本列表
- 遍历数组
- 遍历对象
- 遍历字符串
- 遍历指定次数
- key的原理
- 虚拟DOM中key的作用
- 用index作为key可能会引发的问题
- 如何选择key
Vue学习目录
上一篇:(十一)Vue之条件渲染
基本列表
在vue里基本的列表渲染可以使用v-for指令
v-for指令:
- 用于展示列表数据
- 语法:v-for=“(item, index) in/of xxx” :key=“yyy”
key的作用是唯一标识,在vue或者其他前端框架中,规定只要用了遍历这种方式去生成多个同样结构的数据,必须要给每个结构生成一个标识。 - 可遍历:数组、对象、字符串(用的很少)、指定次数(用的很少)
遍历数组
语法:v-for=“(item, index) in/of xxx” :key=“yyy”
- item:遍历的每一项
- index:遍历的索引
这个key有两种写法:
- 第一种:数组中设置了id,通过key="item.id"配置
- 第二种:索引值,key="index"配置
<ul>
<li v-for="person in persons" :key="person.id">{{person.name}}-{{person.age}}</li>
</ul>
new Vue({
el:'#root',
data:{
persons:[
{id:'001',name:'张三',age:18},
{id:'002',name:'李四',age:19},
{id:'003',name:'王五',age:20}
]
}
});
效果:
遍历对象
语法:v-for=“(value,key) in/of xxx” :key=“yyy”
- value:对象的属性值
- key:对象的属性名
这里的key可以配置属性名,key=“key”,因为在一个对象里边属性名不能有相同的
<ul>
<li v-for="(Value,key) in car" :key="key">{{key}}-{{Value}}</li>
</ul>
new Vue({
el:'#root',
data:{
car:{
name:'奥迪A6',
price:'60万',
color:'黑色'
}
}
});
效果:
遍历字符串
语法:v-for=“(char,index) in/of xxx” :key=“yyy”
- char:字符串的每个字符
- index:每个字符的索引
这里的key可以配置每个字符的索引值,key=“index”
<ul>
<li v-for="(char,index) in str" :key="index">{{char}}-{{index}}</li>
</ul>
new Vue({
el:'#root',
data:{
str:'hello'
}
});
效果:
遍历指定次数
语法:v-for=“(number,index) in/of xxx” :key=“yyy”
- number:指定次数从1开始的整数,包含指定次数的值
- index:每个整数的索引
这里的key可以配置每个字符的索引值,key=“index”
<ul>
<li v-for="(number,index) in 5" :key="index">{{number}}-{{index}}</li>
</ul>
效果:
key的原理
vue中的key有什么作用?(key的内部原理)
虚拟DOM中key的作用
key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据新数据生成新的虚拟DOM,随后Vue进行新虚拟DOM与旧虚拟DOM的差异比较(diff算法)
对比规则:
- (1).旧虚拟DOM中找到了与新虚拟DOM相同的key:
- 若虚拟DOM中内容没变, 直接使用之前的真实DOM!
- 若虚拟DOM中内容变了, 则生成新的真实DOM,随后替换掉页面中之前的真实DOM。
- (2).旧虚拟DOM中未找到与新虚拟DOM相同的key
- 创建新的真实DOM,随后渲染到到页面。
用index作为key可能会引发的问题
-
若对数据进行:逆序添加、逆序删除等破坏顺序操作:
会产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低。 -
如果结构中还包含输入类的DOM:
会产生错误DOM更新 ==> 界面有问题。
例如:
<div id="root">
<button @click.once="add">添加一个赵六</button>
<h2>出现问题</h2>
<!--出现问题-->
<ul>
<li v-for="(person,index) in persons" :key="index">
{{person.name}}-{{person.age}}input type="text">
</li>
</ul>
<h2>没有问题</h2>
<!--没有问题-->
<ul>
<li v-for="(person,index) in persons" :key="person.id">
{{person.name}}-{{person.age}}input type="text">
</li>
</ul>
</div>
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:40}
this.persons.unshift(p)//添加到数组的开头,往后面加使用push
}
}
});
效果:在输入框输入内容,发现使用index作为key,会和不写key一样(因为在vue里面,遍历如果不写key,vue会默认使用索引(index)作为这个遍历的key),会出现结构问题。
如何选择key
最好使用每条数据的唯一标识作为key, 比如id、手机号、身份证号、学号等唯一值。
如果不存在对数据的逆序添加、逆序删除等破坏顺序操作,仅用于渲染列表用于展示,使用index作为key是没有问题的。