部分转自https://blog.csdn.net/cun_king/article/details/120714227

1 v-for指令

1.1 简介

  用于遍历。

  当在组件中使用 v-for 时,key 现在是必须的。它需要一个唯一id

  

1.2 遍历数组

<template>
<p v-for="(item,index) in list" :key="index">索引{{index}}----{{item}}</p>
</template> <script>
export default {
data () {
return {
list:[1,2,3],
}
},
}
</script>

1.3 遍历对象数组

<template>
<p v-for="(item,index) in list" :key="index">索引{{index}}--{{item.name}}--{{item.money}}</p>
</template> <script>
export default {
data () {
return {
list:[
{ "name": "小米手机", "money": 100 },
{ "name": "华为手机", "money": 200 },
{ "name": "苹果手机", "money": 300 },
{ "name": "魅族手机", "money": 400 }
],
}
},
}
</script>

1.4 遍历对象

<template>
<!-- 注意:在遍历对象身上的键值对的时候, 除了 有 val key ,在第三个位置还有 一个 索引 -->
<p v-for="(val, key, i) in list">值是: {{ val }} --- 键是: {{key}} -- 索引: {{i}}</p> </template> <script>
export default {
data () {
return {
list:{
id: 1,
name: '小明',
gender: '男'
},
}
},
}
</script>

1.5 遍历字符串

<body>

    <div id="root">

     <ul>
<li v-for="(value,index) of name">
{{value}}:{{index}}
</li>
</ul> </div> <script type="text/javascript" > const vm = new Vue({
el:'#root',
data:{
name:'杭州历史', }
}) </script>
</body>

2 key属性

2.1 简介

  key在Vue是DOM对象的标识;
  进行v-for列表展示时,不指定key,默认key是index;
  如果数据只做展示使用,使用index作为key是没有任何问题的;
  如果使用index作为key,而后续操作会破坏顺序,一定会带来效率问题,严重时会渲染出错误的DOM

2.2 key的作用

  key就是一个标识,被使用在Vue中。再详细一点,key被使用在Vue中的虚拟DOM中,并不会出现在真实DOM中

2.3 仅展示列表时使用不同的key

2.3.1 示例1-不设置key

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>key的原理</title> <!--引入vue-->
<script type="text/javascript" src="../js/vue.js"></script> </head>
<div id="root">
<h2>人员列表</h2>
<ul>
<li v-for="(p,index) in persons">
{{p.name}}-{{p.age}}
</li>
</ul>
</div>
<body>
<script type="text/javascript">
const vm = new Vue({
el:'#root',
data:{
persons:[
{'id':'001', 'name':'张三','age':'18'},
{'id':'002', 'name':'李四','age':'19'},
{'id':'003', 'name':'王五','age':'20'}
]
}
})
</script>
</body>
</html>

  上述示例html文件中并没有使用到key,似乎也没有问题。当然,单纯地展示数据,不写key是不会存在问题的。

  

2.3.2 设置id为key

<li v-for="(p,index) in persons" :key="p.id">
{{p.name}}-{{p.age}}
</li>

  页面展示结果和上图结果一模一样

  而如果我们在浏览器上查看元素,li上面也不会看到key属性的存在

  

2.3.3 设置index为key

<li v-for="(p,index) in persons" :key="index">
{{p.name}}-{{p.age}}
</li>

  页面效果也是一样的

  截至目前,我们可以得到两个结论:

    

2.3.4 小结 

  1) 只做数据展示用,不写key是没有任何影响的;

  2)key不会出现在真实DOM中

  3)实际上,即使不写key,Vue在生成真实DOM时,也用到了key,默认是数据索引(index)

2.4 不仅仅是展示的时候

  在展示人员信息的基础上显示索引,并且添加一个按钮,功能是在头部添加人员信息

2.4.1 示例 index作为key

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>key的原理</title> <!--引入vue-->
<script type="text/javascript" src="../js/vue.js"></script>
<link rel="icon" href="../favicon.ico" type="image/x-icon" /> </head>
<div id="root">
<h2>人员列表</h2>
<button @click="add">添加一个老刘</button>
<ul>
<li v-for="(p,index) in persons" :key="index">
{{p.name}}-{{p.age}}-{{index}}
</li>
</ul>
</div>
<body>
<script type="text/javascript">
const vm = new Vue({
el:'#root',
data:{
persons:[
{'id':'001', 'name':'张三','age':'18'},
{'id':'002', 'name':'李四','age':'19'},
{'id':'003', 'name':'王五','age':'20'}
]
},
methods:{
add(){
const p = {'id':'004', 'name':'老刘','age':'40'}
this.persons.unshift(p)
}
}
})
</script>
</body>
</html>

  点击按钮,添加一个新人物,这个时候索引发生了变化,新添加的人物“老刘”变为了索引0。

  也就是说,使用index作为key,那么元素的index是可能会变化的

2.4.2 示例 index作为key

  不展示索引了,改为输入框,在每个人物后面的输入框内写上人物的姓,观察新插入数据后原始数据的变化

<li v-for="(p,index) in persons" :key="index">
{{p.name}}-{{p.age}}
<input type="text">
</li>

  在输入框中输入内容,效果如上图所示,似乎没有什么不对,接下来就是见证奇迹的时刻

  添加老刘,出现了问题,和我们预想的不一样。如下图,输入框和姓名对不上了。

  

2.4.3 id作为key

如果修改为数据的唯一标识,则不会产生这样的问题
<li v-for="(p,index) in persons" :key="p.id">
{{p.name}}-{{p.age}}
<input type="text">
</li>

如下图,添加老刘后,名字和输入框还是对应的

3 key的原理

  那么为什么使用index作为key会出现上面的问题的,二使用id就不会呢?

3.1 虚拟dom

  要解释key的实现原理,就要引入Vue一个十分重要的概念——虚拟DOM。

  给出一组数据和模板,Vue要把这些数据渲染到页面上,首先要生成虚拟DOM,然后根据虚拟DOM去生成真实的DOM,真实的dom就是页面上显示的。如果数据发生了改变,Vue会生成新的虚拟DOM,然后再去生成新的真实DOM,关键就是这个新的真实DOM的生成方式了。

  并不是直接通过新的虚拟DOM生成新的真实DOM,否则虚拟DOM一点用处也没有了。Vue的操作是,拿新的虚拟DOM与之前的旧的虚拟的DOM去做比较,这个比较通过key来对应的,会把key相同的新旧虚拟DOM进行比较。如果相同,直接延用之前虚拟dom生成的真实dom即可,如果不同,则生成新的真实DOM对象。

3.2 过程分析

3.2.1 key为index的情况

  根据数据生成真实DOM的流程如下:(注意,下图的真实DOM中输入框里的内容为生成页面后手动添加)

  然后,添加人物“老刘”,获取到一组新数据

  Vue拿新数据生成新的虚拟DOM,注意,由于老刘放到了数组最前面,所以数组里面的数据的index发生了变化

  在生成真实DOM时,就需要用新生成的虚拟DOM和原来的虚拟DOM作比较(一条一条分析)

  对比第一条,key为0,找到旧DOM中key为0的数据,发现“老刘-40”和“张三-18”不同,创建新的真实DOM;再往后,发现输入框一致(注意,比较的是虚拟DOM,输入框里面是没有输入的文字的,所以是一致的),不必重新渲染,直接使用原来真实DOM的内容。第一条内容就出现了,而这个输入框还携带有张三的姓

  对比第二条,key为1,找到旧DOM中key为1的数据,发现“张三-18”和“李四-19”不同,创建新的真实DOM;再往后,发现输入框一致,不必重新渲染,直接使用原来真实DOM的内容。第二条内容就出现了,而这个输入框还携带有李四的姓

  之后同理

  回顾这个过程,key是作为虚拟DOM中对象的唯一标识,标识出了数据的“身份信息”,Vue在虚拟DOM中会根据这个“身份标识”去对比内容,设计的初衷是为了节省资源开支,不必渲染重复的部分。在本示例中,不但带来了效率问题,还渲染出了错误的DOM,后果非常严重

3.2.2 key为id的情况

  直接进入添加“老刘”后的新旧DOM对比

  

  对比第一条,key为‘004’,发现在旧DOM中并不存在,直接生成新的真实的DOM。

  对比第二条,key为‘001’,发现旧DOM中key为‘001’的数据相同,直接将原来的真实的DOM拿过来使用。

  ……

  最后生成正确的DOM,节省了资源开支

Vue15 v-for和key的作用及原理的更多相关文章

  1. v-for中key的作用与原理

    一.虚拟DOM中key的作用 key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据新数据生成新的虚拟DOM,随后Vue会对新虚拟DOM与旧虚拟DOM的差异进行比较. 二.如何选择key 最好使 ...

  2. (转)Vue种key的作用

    https://blog.csdn.net/qq_41861679/article/details/80659278 https://cn.vuejs.org/v2/api/#key 其实不只是vue ...

  3. vue中key的作用 v-for里警告 v-if的复用

    vue总是会复用页面上已经存在的dom,区别的方法是加上key就可以,还设有v-for时候的警告也是如此key的作用是区别这条跟那条的.<body> <div id="ap ...

  4. 图解vue中 v-for 的 :key 的作用,虚拟dom Diff算法

    其实不只是vue,react中在执行列表渲染时也会要求给每个组件添加上key这个属性. 要解释key的作用,不得不先介绍一下虚拟DOM的Diff算法了. 我们知道,vue和react都实现了一套虚拟D ...

  5. react key的作用

    react中的key属性,它是一个特殊的属性,它是出现不是给开发者用的(例如你为一个组件设置key之后不能获取组件的这个key props),而是给react自己用的. 简单来说,react利用key ...

  6. Vue中使用key的作用

    key的作用是为了在diff算法执行时更快的找到对应的节点,提高diff速度 key具有唯一性 vue中循环需加 :key=“唯一标识” ,唯一标识可以使item里面id index 等,因为vue组 ...

  7. vue key的作用

    key的作用是什么? 简单来说: key是给每一个vnode的唯一id,可以依靠key,更准确, 更快的拿到oldVnode中对应的vnode节点. 1. 更准确 因为带key就不是就地复用了,在sa ...

  8. v-for中的key的使用【key的作用主要是是为了高效的更新虚拟DOM】

    vue中列表循环需加:key="唯一标识" 唯一标识可以是item里面id index等,因为vue组件高度复用增加Key可以标识组件的唯一性,为了更好地区别各个组件 key的作用 ...

  9. vue中:key 和react 中key={} 的作用,以及ref的特性?

    vue中:key 和react 中key={} 为了给 vue 或者react 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key 属性 一句话概括就是 ...

  10. ON DUPLICATE KEY UPDATE作用

    ON DUPLICATE KEY UPDATE作用 先声明一点,ON DUPLICATE KEY UPDATE为Mysql特有语法,这是个坑 语句的作用,当insert已经存在的记录时,执行Updat ...

随机推荐

  1. 陪你去看 Lodash.js 起步

    lodash 起步(数组) Lodash 是一个较为流行的 JavaScript 的实用工具库. 在开发过程中如果能熟练使用一些工具库提供的方法,有利于提高开发效率. 笔者从 API 上入手,不分析其 ...

  2. Stream流使用

    Stream流的使用 转换为流的操作 map转换为stream流 Map map = new HashMap(); Set<Map.Entry<String,Integer>> ...

  3. Huawei OJ 题解 - 31. 整数拆分 - Go 参考解答

    ## 简介- 详情:http://oj.rnd.huawei.com/problems/31/details- 难度:简单## 思路TODO## 用例TODO## 解答```gopackage mai ...

  4. ChatGPT 可以联网了!浏览器插件下载

    Twitter 用户 An Qu 开发了一款新的 Chrome 插件帮助 ChatGPT 上网,安装插件以后 ChatGPT 就可以联!网!了! 简单来说开启插件后,他可以从网上搜索信息,并且根据用户 ...

  5. Jenkins&&gitlab2

    Jenkins  slave 添加jenkins slave节点: jenkins slave节点创建工作目录与基本环境配置,如果jenkins slave节点需要clone代码和执行java 代码编 ...

  6. python 定时发送邮件

    import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart f ...

  7. Safari浏览器对SVG中的<foreignObject>标签支持不友好,渲染容易错位

    在 svg 中需要写一个 markdown 编辑器,需要用到 <foreignObject> 绘制来html,编辑器选择了 simplemde.大致html部分结构如下,<markd ...

  8. 如何自定义调整bootstrap的模态框大小

    背景 项目遇到一个需求,一个大表格放到模态框中,总是会出现撑开的效果,换了文档最大的modal-lg样式还不能解决,原因就是官方不支持更大号的模态框,需要自定义. 经过尝试理解,总结出调整模态框大小通 ...

  9. Windows关闭网络防火墙教程

    Win10操作系统 1. 打开控制面板,点击"系统和安全" 2. 点击"Windows Defender 防火墙" 3. 点击"启用或关闭Window ...

  10. yolov5数据集制作 数据集分割+voc格式转txt格式代码

    先上数据集分割代码 网上没找到合适的 自己写了一个 分割比例为0.6 :0.2 :0.2 import os import random oriImgDir = "./change14img ...