文档: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就不会就地复用,性能会相对低一点了。

最新文章

  1. Android Studio Eclipse Code Formatter
  2. Ubuntu下使用SVN
  3. 关于内存管理/set/get方法
  4. sql server 2008 提示评估期已过的解决方法(升级无效)
  5. C#实现Dll(OCX)控件自动注册的两种方法
  6. MatLab计算图像圆度
  7. 简单的LRU Cache设计与实现
  8. (Problem 40)Champernowne&#39;s constant
  9. jquery的校验规则的方法
  10. CEOI 2014 wall (最短路)
  11. java乱码问题处理
  12. 21.Linux-写USB键盘驱动(详解)
  13. HTML HTML5 新特性
  14. less环境的安装与搭建
  15. CMDB服务器管理系统【s5day92】:服务器管理回顾
  16. YARN的三种调度器的使用
  17. maven名词解释
  18. SVN怎么触发Jenkins自动构建
  19. 2018.06.26 NOIP模拟 号码(数位dp)
  20. Openstack 网络服务 Neutron计算节点部署(十)

热门文章

  1. Mysql 5.7 账户过期重启
  2. 常用的js工具函数
  3. setTimeout的异步传输机制
  4. CellSet 遍历
  5. 原创 html动态表格
  6. Ubuntu11.04 安装cuda4.3
  7. [LoadRunner]录制启动时报“The JVM could not be started……”错误解决方案
  8. Android商城开发系列(三)——使用Fragment+RadioButton实现商城底部导航栏
  9. Vijos P1243 生产产品 (单调队列优化DP)
  10. asp页面无法访问,可尝试开始SQL Server等服务