部分转自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. 洛谷 P4135 作诗 题解

    题面. 之前做过一道很类似的题目 洛谷P4168蒲公英 ,然后看到这题很快就想到了解法,做完这题可以对比一下,真的很像. 题目要求区间内出现次数为正偶数的数字的数量. 数据范围1e5,可以分块. 我们 ...

  2. RSA、DSA 和 ECC 加密算法有什么区别?

    RSA.DSA 和 ECC 加密算法是用于在公钥基础设施中生成密钥的主要算法. 公钥基础设施 (PKI) 用于管理互联网通信和计算机网络中的身份和安全性. 启用 PKI 的核心技术是公钥密码术,这是一 ...

  3. UBOOT编译--- UBOOT的编译和链接选项详解(六)

    1. 前言 UBOOT版本:uboot2018.03,开发板myimx8mmek240. 2. 函数 cc-option 编译选项变量cc-option 定义在 scripts/Kbuild.incl ...

  4. JSP利用AJAX实现页面即时校验验证码

    在JSP页面实现验证码校验文章中当时是使用的Servlet类来进行的验证码校验,但是这种方式并不能即时校验,在正常情况下都是直接在用户输入之后就进行校验,这样对用户来说很方便的. AJAX 即&quo ...

  5. Springboot 2.3.1配置拦截器遇到的坑

    1.多个配置类继承WebConfigureSupport或实现WebConfigure接口导致拦截器失效 2.拦截器中的bean无法正常注入,SpringBoot项目的Bean装配默认规则是根据App ...

  6. 【大数据面试】【框架】Hive:架构、计算引擎、比较、内外部表、by、函数、优化、数据倾斜、动静态分区

    一.组成 1.架构 源数据原本是存在dubby数据库,存在MySQL可以支持多个客户端 客户端.数据存储(HDFS).MR计算引擎 2.计算引擎的选择 MR引擎:基于磁盘,计算时间长,但一定能算出结果 ...

  7. python注释、变量、数据类型详细

    目录 1.python注释 2.PEP8规范 3.变量与常量 1.python中的变量 2.变量名的命名规范 3.常量的基本使用 1.python注释 什么是注释? 注释是对代码的解释说明,写注释是为 ...

  8. Docker容器入门到精通

    Docker 容器 快速入门 第一章:Docker容器 第二章:Dockerfile指令与Docker-compose容器编排-搭建docker私有仓库 h1 { color: rgba(0, 60, ...

  9. 基于.NetCore开发博客项目 StarBlog - (22) 开发博客文章相关接口

    前言 本文介绍博客文章相关接口的开发,作为接口开发介绍的第一篇,会写得比较详细,以抛砖引玉,后面的其他接口就粗略带过了,着重于WebApi开发的周边设施. 涉及到的接口:文章CRUD.置顶文章.推荐文 ...

  10. Spring IOC官方文档学习笔记(三)之依赖项

    1.依赖注入 (1) 依赖注入(DI)的概念:某个bean的依赖项,由容器来负责注入维护,而非我们自己手动去维护,以此来达到bean之间解耦的目的,如下 //情况一:不使用依赖注入 public cl ...