VUE--列表渲染(v-for)及key的使用

v-for用法

<div v-for="item in items">
    {{item.text}}
</div>
或
<div v-for="(item,index)in items">
    {{item.text}}
</div>

v-for的默认行为会尝试原地修改元素而不是移动它们,即“就地更新”策略。如果数据项的顺序发生改变,vue将不会移动DOM元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。也就是说默认的情况下vue会尽量使用已经存在的DOM元素,直接在已有的DOM上进行复用修改,这样可以带来一定性能上的提升。

<!-- 开发环境版本,包含了有帮助的命令行警告 -->
<!DOCTYPE html>
<html>
<head>
  <title>My first Vue app</title>
  <!--<script src="https://unpkg.com/vue"></script> -->
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>
<body>
  <div id="app" > 
	<div v-for="(item,i) in list" :key="i">
	    {{item}}{{i}}
		<input :class="classData[i]">
			<button @click="handleDelete(i)">delete</button>
		</div> 
  </div>
  
  <script>
    var app = new Vue({
      el: '#app',
      data: {
		list:[{id:1,value:'A'},{id:2,value:'B'},{id:3,value:'C'}],
		classData:['A','B','C']
      },
	  methods:{
		  handleDelete(i){		
			this.list.splice(i,1)
	      }
	  }
    })
  </script>
</body>
</html>

问题:删除第二项,但是好像把第三项删除了。实际上变化:vue经过比对发现第二项数据被删除了,即list[1]被删除了,list变为[{"id":1,value:"A"},{"id":2,value:"C"}],所以列表只需要渲染这两个数据。渲染时会复用第二个div的DOM结构,也就是直接把第二个div改成了第一个div。

第二个div被删除了,但是input里面的值还在?这就是vue就地更新的一个缺陷,因为这里input是临时DOM状态,在元素复用时,input里的值也会被保留。

v-for联合key可解决上述问题

key

key绑定item.id效果符合预期。

v-for的默认行为尝试原地修改元素而不是移动它们。要强制其重新排序元素,需要用特殊attribute key来提供一个排序提示;

建议尽可能在使用v-for时提供key attribute,除非遍历输出的DOM内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。

因为它是vue识别节点的一个通用机制,key并不仅与v-for特别关联。

key的特殊attribute主要用在vue的虚拟DOM算法,在新旧nodes对比时辨识VNodes.如果不使用key,vue会使用一种最大限度减少动态元素并且尽可能的尝试就地修改/复用相同类型元素的算法。而使用key时,它会基于key的变化重新排列元素顺序,并且移除key不存在的元素。

有相同父元素的子元素必须有独特的key.重复的key会造成渲染错误。

它也可以用于强制替换元素/组件而不是重复使用它

key的作用主要是为了高效的更新虚拟DOM; 当以index为key值时,如果数组长度发生变化,会导致key的变化,比如删除其中某一项,那么 index会相应变化。所以当用index作为key和不加index没什么区别,都不能提升性能。一般 使用每项数据的唯一值作为key,就算数组长度发生变化,也不会影响到这个key

vue和react的虚拟DOM的diff算法大致相同,其核心是基于两个简单的假设:

1、两个相同的组件产生类似的DOM结构,不同的组件产生不同的DOM结构;

2、同一层级的一组节点,他们可以通过唯一的id进行区分。

基于以上两点假设,使得虚拟DOM的Diff算法的复杂度从O(n^3)降到了O(n)


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值