简介
v-for更新已渲染过得元素列表时,默认采用“就地复用策略”。如果数据项顺序改变,vue不是移动dom而是简单复用此处每个元素,并确保它在特定索引下显示已被渲染的元素。
<li v-for="user in list" :key="user.id">
演示
迭代简单数组
<body>
<div id="content">
<ul>
<li v-for="(item,i) in list">索引:{{i}}--值:{{item}}</li>
</ul>
</div>
</body>
<script>
var vm = new Vue({
el:"#content",
data:{
list:[0,1,2,3,4,5,6]
}
});
</script>
运行:
迭代对象数组
//html
<div id="objContent">
<ul>
<li v-for="(user,i) in list" :key="i">索引:{{i}}--姓名:{{user.name}}--年龄:{{user.age}}</li>
</ul>
</div>
//js
var objVm = new Vue({
el: "#objContent",
data: {
list: [
{name:"zhangsan",age:18},
{name:"lisi",age:20},
{name:"wangwu",age:26}
]
}
});
运行:
迭代对象属性
//html
<div id="fliedContent">
<ul>
<li v-for="(val,key,index) in user" :key="index">索引:{{index}}--属性名:{{key}}--值:{{val}}</li>
</ul>
</div>
//js
var fliedVm = new Vue({
el: "#fliedContent",
data: {
user:{
id:88,
name:"wangwu",
age:18
}
}
});
运行:
迭代数字
<div id="countContent">
<p v-for="i in 6" :key="i">第{{i}}个P标签</p>
</div>
//js
//必须为区域指定vue对象,否则v-for不奏效
var countVm = new Vue({
el: "#countContent",
});
运行:
运行(注意迭代数字索引从1开始,而不是0):
案例:数组首尾添加元素
思路
js的push()函数可以在数组尾部添加元素。
js的unshift()函数可以在数组头部添加元素。
实现
尾部添加与头部添加
//html
<div id="content">
<label for="idInput">id:</label><input type="text" id="idInput" v-model="idInput" />
<label for="nameInput">名称:</label><input type="text" id="nameInput" v-model="nameInput" />
<button v-on:click="addEnd">尾部添加</button>
<button v-on:click="addStart">头部添加</button>
<br>
<ul>
<li v-for="user in list">
<input type="checkbox" />
id:{{user.id}}---名称:{{user.name}}
</li>
</ul>
</div>
//
<script>
var vm = new Vue({
el: "#content",
data: {
idInput: "",
nameInput: "",
list: [
{ id: 1, name: "张三" },
{ id: 2, name: "李四" },
{ id: 3, name: "王五" },
{ id: 4, name: "赵柳" },
{ id: 5, name: "郭达" }
]
},
methods: {
addEnd() {
this.list.push( { id: this.idInput, name: this.nameInput } );
},
addStart() {
this.list.unshift( { id: this.idInput, name: this.nameInput } );
}
}
});
</script>
运行:
尾部添加:
头部添加:
勾选后添加
上面的功能完全正常,而勾选元素后在尾部添加,也没有问题,但是当勾选后进行了头部添加,出现了勾选错位的问题:
勾选:
头部添加出现错位,显然这是因为vue在重新渲染时不移动dom顺序导致的,其只记录了被勾选的位置,没有记录被勾选的“身份”。:
官方文档有阐述,可以使用key属性追踪节点身份,PS:vue.js 2.2.0+版本后key是必须的。于是修改代码:
<li v-for="user in list" v-bind:key="user">
但是报错了:
看来是key绑定了object导致的,正确方法应该是绑定string/number类型的数据,那么本例中id可以满足需求:
<li v-for="user in list" v-bind:key="user.id">
运行,勾选:
添加,正确运行:
完整代码
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="js/vue.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<div id="content">
<label for="idInput">id:</label><input type="text" id="idInput" v-model="idInput" />
<label for="nameInput">名称:</label><input type="text" id="nameInput" v-model="nameInput" />
<button v-on:click="addEnd">尾部添加</button>
<button v-on:click="addStart">头部添加</button>
<br>
<ul>
<li v-for="user in list" v-bind:key="user.id">
<input type="checkbox" />
id:{{user.id}}---名称:{{user.name}}
</li>
</ul>
</div>
<script>
var vm = new Vue({
el: "#content",
data: {
idInput: "",
nameInput: "",
list: [
{ id: 1, name: "张三" },
{ id: 2, name: "李四" },
{ id: 3, name: "王五" },
{ id: 4, name: "赵柳" },
{ id: 5, name: "郭达" }
]
},
methods: {
addEnd() {
this.list.push( { id: this.idInput, name: this.nameInput } );
},
addStart() {
this.list.unshift( { id: this.idInput, name: this.nameInput } );
}
}
});
</script>
</body>
</html>