- v-for渲染列表
- 维护状态
- 数组变异方法与替换数组
- $set、$remove
- 对象属性实现列表渲染
一、v-for渲染列表
语法:v-for="item in items"
先来看示例:
1 <style> 2 *{ 3 margin: 0; 4 padding: 0; 5 list-style: none; 6 } 7 ul{ 8 margin: 100px; 9 } 10 li{ 11 line-height: 30px; 12 } 13 p{ 14 display: inline-block; 15 } 16 span{ 17 border: 1px solid red; 18 color: red; 19 padding: 2px; 20 font-size: 12px; 21 } 22 </style>
1 <ul id='example'> 2 <li v-for="item in newList"> 3 <p>{{item.title}}</p> 4 <span v-if="item.new">新</span> 5 </li> 6 </ul> 7 <script> 8 var vm = new Vue({ 9 el:'#example', 10 data:{ 11 newList:[ 12 { 13 title:"张柏芝第三胎生父", 14 new:true, 15 id:0 16 }, 17 { 18 title:"被约谈艺人名单", 19 new:true, 20 id:1 21 }, 22 { 23 title:"弑母男孩指认现场", 24 new:false, 25 id:2 26 }, 27 { 28 title:"任贤齐胖到200斤", 29 new:true, 30 id:3 31 },{ 32 title:"韩国解说员流鼻血", 33 new:false, 34 id:4 35 } 36 ] 37 } 38 }); 39 </script>
渲染效果:
1.1维护状态
在javascript中for作为循环遍历的特性来理解,如果列表的节点发生变化时,v-for指令就会从新遍历数据渲染页面,比如添加,删除,替换节点操作,这种情况下一般会有原本没有发生变化的节点被重新渲染,vue给出了解决方案就是在每一项上添加一个唯一标识:v-bind:key="ID",id为数据中提供的唯一标识,有了这个唯一标识在节点发生变化时,没有变化的节点会重用,不会重复渲染,这样就大大增强了渲染效率。所以在上面的示例中可以添加这样一个唯一标识:
<li v-for="item in newList" :key="item.id">
1.2数组变异方法
在javascript中向数组中修改数组的元素值时,通常都采用索引的方式来修改,在vue中同样可行,比如将上面示例的第二项的title修改成“模特核电站不雅照”,视图也会同样触发从新修改。
vm.newList[1].title="模特核电站不雅照";//这样的数据修改可以触发相关项的节点渲染
但是这种索引的方式并不是万能的,比如:vm.newList[2]="";这个数据变化就不会触发页面的渲染,还有比如:vm.newList[5]={title:"泰妍自曝患抑郁症",new:true,id:5},这个添加数据也不会触发页面渲染,这种情况就需要用到vue的数组变异方法和替换方法了:
push()在数组后面添加一组数据,并且触发页面渲染(在上面的示例基础上操作): vm.newList.push({title:"冰毒成为头号毒品",new:true,id:6}); push()方法会把组数据渲染到列表的最后面。
unshift()在数组的最前面添加一组数据,并且触发页面渲染(渲染到列表的最上面): vm.newList.unshift({title:"模特核电站不雅照",new:false,id:7}); 。
shift()删除第一组数据;
pop()删除最后一组数据;
splice()删除并向数据中添加新的数据,与js数组的效果一致,如果不写入添加数据,就同等与在数据中删除指定的数据,会触发页面渲染。
sort()排序;
reverse()颠倒数据顺序;
1.3替换数组
所谓替换数组就是将列表数据指向从原来的数组完全改变指向另一个数组,比如js数组的filter()、concat()、slice()这些方法总是返回一个全新的数组,其实非常的简单,直接改变数据指向即可,例如基于上面示例操作: vm.newList = [{title:"我是全新数组的第一项title",new:true,id:0}] 执行这行代码后,就被替换成了一个全新的数组,页面刷新只有当前数组的一项渲染数据。
1.4$set、$remove
在js中通过索引对数据进行进行局部操作是最精确最有效的一种方式,但是在前面的数组变异方法中我提到了采用数组索引方式不能触发视图更新,别着急,vue给我们提供了一个可以实现索引操作数据并触发视图更新的方法:
Vue.set语法:Vue.set(vm.items, indexOfItem, newValue),Vue的全局方法set;
vm.$set语法vm.$set(vm.items, indexOfItem, newValue),Vue的实例方法$set();
也可以使用变异方法splice()来实现:vm.items.spleice(indexOfIndex, 1, newValue)。
如果是需要改变数组长度的话可以使用这样的方式:vm.items.splice(newLength)。
例如根据上面的示例修改索引为3的数据:
Vue.set(vm.newList, 3, {title:"我从三变成了6", new:true,id:6}) 但是需要注意的是如果没有索引为3的这组数据的话会出错。
vm.$set(vm.newList, 4, {title:"我从4变成了8", new:true,id:8}) 这其实没有区别,但是如果存在作用域反问层级多的话采用这个映射方法效率应该要高一些。
如果需要改变数组长度的话就直接使用splice解决,然后 vm.newList.splice(2);
最后关于$remove的使用,前面提到过可以使用变异方法splice()实现,而$remove就是splice的语法糖(这里遇到一些问题,暂时没解决)。
二、对象属性实现列表渲染
1 <ul id='example'> 2 <li v-for="(value,key,index) in newObj">{{value}}--{{key}}--{{index}}</li> 3 </ul> 4 <script> 5 var vm = new Vue({ 6 el:'#example', 7 data:{ 8 newObj:{ 9 name:"他乡踏雪", 10 sex:"男", 11 age:18 12 } 13 14 } 15 }); 16 </script>
渲染结果:
这个简单的示例可以看到在v-for="(par1, par2, par3) in newObj"中的获取的数据分别是属性值、属性名称、属性索引。
2.1对象列表渲染数据更新
直接通过对象属性更新属性值可以触发页面渲染,比如 vm.newObj.name = "他乡踏雪~丹" ,但是直接采用点语法添加属性或者采用对象方法删除属性就不能触发页面渲染。这时候同样使用vue的$set()方法,例如 vm.$set(vm.newObj,"skill","vue"),这行代码就可以新增一个对象属性skill,并且将值“vue”渲染到页面;也可以通过$set()方法更新指定属性的值。
最后,注意一种情况就是v-for指令的优先级大于v-if,也就是说在同一个标签中出现了这两个指令,当v-if的值为false时,依然会触发列表渲染,v-if失效。遇到这种情况最好使用<template>标签包括来实现v-if触发。