vue之列表循环
文档:https://cn.vuejs.org/v2/guide/list.html
当 Vue.js 用
v-for
正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。这个类似 Vue 1.x 的track-by="$index"
意思就是,默认就是按照索引来“就地复用”html元素的,如以下代码
<div v-for="(item,index) in arr" :key="index">
等价于
<div v-for="(item,index) in arr">
对于“就地复用”这个现象,以下来重现一下:
测试代码
<template>
<div>
<div v-for="(item,index) in arr">
<input type="text">
<button @click="del(index)">删除</button>
</div>
<button @click="add">添加</button>
</div>
</template> <script>
export default {
name: "App",
data() {
return {
arr: [
"1",
"2",
"3",
]
}
},
methods: {
del(index) {
this.arr.splice(index, 1);
},
add() {
this.arr.push("");
}
}
}
</script>
往页面的输入框依次填入1~3:
然后点击第二个删除按钮,效果如下:
页面剩下1、2,这跟我们预期的剩下1、3不一样,原因就在于vue默认的“就地复用”原则。现象解释如下:
将以上三个输入框记为a,b,c。for循环默认的key为索引的话,则a对应0,b对应1,c对应2 。那当删了了第二个元素时,新数组的元素的索引分别为0和1,而重新渲染时,采用就地复用的话,复用到的dom元素就是a和b了,页面输入框就展示1和2了。这输入框中的1和2实际上就是代表了dom的状态,通过输入框的值,就能看出来,vue复用了哪个dom元素。这里说的,实际上就是对应了文档的第二段话:
这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出
也就是说,当dom有状态的时候,最好就不要采用这种默认模式(key为索引),否则会导致状态混乱(如上面我们明明点击了第二个删除,而页面展示的效果却像点击了第三个删除的按钮一样)。
对于循环渲染有状态的dom元素,应该让key与数组元素一一对应起来,这样数组元素的删除,就完全等同于对应dom元素的删除了(换个角度解释以上的问题就是:点击删除的前后,索引1对应着相同的dom元素,而对应的数组元素却不一致,导致页面展示的结果让人困惑),解决办法如下:
<div v-for="(item,index) in arr" :key="item">
<input type="text">
<button @click="del(index)">删除</button>
</div>
让key与数组元素唯一对应起来即可,运行效果:点击第二个删除,界面上剩余1,3,符合我们预期结果。但是这样一来,vue就不会就地复用,性能会相对低一点了。
最新文章
- Android Studio Eclipse Code Formatter
- Ubuntu下使用SVN
- 关于内存管理/set/get方法
- sql server 2008 提示评估期已过的解决方法(升级无效)
- C#实现Dll(OCX)控件自动注册的两种方法
- MatLab计算图像圆度
- 简单的LRU Cache设计与实现
- (Problem 40)Champernowne&#39;s constant
- jquery的校验规则的方法
- CEOI 2014 wall (最短路)
- java乱码问题处理
- 21.Linux-写USB键盘驱动(详解)
- HTML HTML5 新特性
- less环境的安装与搭建
- CMDB服务器管理系统【s5day92】:服务器管理回顾
- YARN的三种调度器的使用
- maven名词解释
- SVN怎么触发Jenkins自动构建
- 2018.06.26 NOIP模拟 号码(数位dp)
- Openstack 网络服务 Neutron计算节点部署(十)
热门文章
- Mysql 5.7 账户过期重启
- 常用的js工具函数
- setTimeout的异步传输机制
- CellSet 遍历
- 原创 html动态表格
- Ubuntu11.04 安装cuda4.3
- [LoadRunner]录制启动时报“The JVM could not be started……”错误解决方案
- Android商城开发系列(三)——使用Fragment+RadioButton实现商城底部导航栏
- Vijos P1243 生产产品 (单调队列优化DP)
- asp页面无法访问,可尝试开始SQL Server等服务