Vue指令之v-for
和key
属性
- 迭代数组
<ul><li v-for="(item, i) in list">索引:{{i}} --- 姓名:{{item.name}} --- 年龄:{{item.age}}</li>
</ul>
- 迭代对象中的属性
<!-- 循环遍历对象身上的属性 -->
<div v-for="(val, key, i) in userInfo">{{val}} --- {{key}} --- {{i}}</div>
- 迭代数字
<p v-for="i in 10">这是第 {{i}} 个P标签</p>
2.2.0+ 的版本里,当在组件中使用 v-for 时,key 现在是必须的。
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用 “就地复用” 策略。如果数据项的顺序被改变,Vue将不是移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。
为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性。
示例1:迭代数组
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head><meta charset="UTF-8"><title>Title</title></head>
<body><div id="app"><ul><li v-for="(item, i) in list">索引:{{i}} --- 姓名:{{item.name}} --- 年龄:{{item.age}}</li></ul></div><!-- 1.导入vue.js库 --><script src="lib/vue.js"></script><script>// 2. 创建一个Vue的实例var vm = new Vue({el: '#app',data: {list: [{ "name":"张一", "age": 31},{ "name":"张二", "age": 21},{ "name":"张三", "age": 41},{ "name":"张四", "age": 51},{ "name":"张五", "age": 61},],},methods:{}})</script></body>
</html>
浏览器显示如下:
示例2:迭代对象中的属性
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head><meta charset="UTF-8"><title>Title</title></head>
<body><div id="app"><!-- 循环遍历对象身上的属性 --><div v-for="(val, key, i) in userInfo">value值:{{val}} --- key值:{{key}} --- 索引:{{i}}</div></div><!-- 1.导入vue.js库 --><script src="lib/vue.js"></script><script>// 2. 创建一个Vue的实例var vm = new Vue({el: '#app',data: {userInfo: {userid: 1,username: "张三",age: 30}},methods:{}})</script></body>
</html>
浏览器显示如下:
示例3: 迭代数字
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head><meta charset="UTF-8"><title>Title</title></head>
<body><div id="app"><p v-for="i in 15">这是第 {{i}} 个P标签</p></div><!-- 1.导入vue.js库 --><script src="lib/vue.js"></script><script>// 2. 创建一个Vue的实例var vm = new Vue({el: '#app',data: {},methods:{}})</script></body>
</html>
浏览器显示如下:
v-for中使用key的注意事项
2.2.0+ 的版本里,当在组件中使用 v-for 时,key 现在是必须的,因为没有key来保障循环中的唯一性,那么组件则会被打乱。
下面来看一个例子,明确当不用key的时候会出现什么样的问题。
不用key的问题示例
<!DOCTYPE html>
<html lang="en" xmlns:v-bind="http://www.w3.org/1999/xhtml">
<head><meta charset="UTF-8"><title>Title</title></head>
<body><div id="app"><div><label>Id:<input type="text" v-model="id"></label><label>Name:<input type="text" v-model="name"></label><input type="button" value="添加" @click="add"></div><p v-for="item in list" ><input type="checkbox">{{item.id}} --- {{item.name}}</p></div><!-- 1.导入vue.js库 --><script src="lib/vue.js"></script><script>// 2. 创建一个Vue的实例var vm = new Vue({el: '#app',data: {id: '',name: '',list: [{ id: 1, name: '李斯' },{ id: 2, name: '嬴政' },{ id: 3, name: '赵高' },{ id: 4, name: '韩非' },{ id: 5, name: '荀子' }]},methods:{add(){// 添加新的数据到队列最后this.list.push({ id: this.id, name: this.name })}}})</script></body>
</html>
浏览器显示如下:
可以从上面的示例中看到,当添加数据到最后的情况下,原来勾选的5 --- 荀子并没有影响到顺序。
下面看看,如果将数据插入到前面会怎么样?
使用unshift()
方法,将数据添加到队列的最前面,如下:
那么,再来执行一下上面的示例,如下:
<p v-for="item in list" ><input type="checkbox">{{item.id}} --- {{item.name}}</p>
那么这时候就要给上面的组件设置一个key,并且绑定一个string/number类型的数据来保障循环数据的唯一性。
这样才能保障渲染。
使用v-bind设置key的值,保障渲染的数据顺序
<!-- 注意: v-for 循环的时候,key 属性只能使用 number获取string --><!-- 注意: key 在使用的时候,必须使用 v-bind 属性绑定的形式,指定 key 的值 --><!-- 在组件中,使用v-for循环的时候,或者在一些特殊情况中,如果 v-for 有问题,必须 在使用 v-for 的同时,指定 唯一的 字符串/数字 类型 :key 值 --><p v-for="item in list" :key="item.id"><input type="checkbox">{{item.id}} --- {{item.name}}</p>
再次执行一下刚才错误的过程,如下: