八、vue-基础之列表渲染v-for、v-for中的key属性的作用

news/2024/4/24 20:11:37/

一、v-for列表渲染

在真实开发中,我们往往会从服务器拿到一组数据,并且需要对其进行渲染。

  • 这个时候我们可以使用v-for来完成;
  • v-for类似于JavaScript的for循环,可以用于遍历一组数据;

 

二、v-for基本使用

(1)遍历数组

我们直接上demo~ 

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><div id="app"><!-- 1. 遍历数组 --><!-- 2. 遍历对象 --><ul><!-- 2.1 一个参数 --><li v-for="value in info">{{value}}</li></ul><ul><!-- 2.2 两个参数 --><li v-for="(value, key) in info">{{value}} - {{key}}</li></ul><ul><!-- 2.3 三个参数 --><li v-for="(value, key, index) in info">{{value}} - {{key}} - {{index}}</li></ul></div><script src="../lib/vue.js"></script><script>const app = Vue.createApp({// data: option apidata() {return {message: "Hello Vue",movies: [],info: { name: "daxia", age: 18, height: 1.88 },}},})app.mount("#app")</script></body>
</html>

(2) 遍历对象

 

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><div id="app"><!-- 1. 遍历数组 --><!-- 2. 遍历对象 --><ul><!-- 2.1 一个参数 --><li v-for="value in info">{{value}}</li></ul><ul><!-- 2.2 两个参数 --><li v-for="(value, key) in info">{{value}} - {{key}}</li></ul><ul><!-- 2.3 三个参数 --><li v-for="(value, key, index) in info">{{value}} - {{key}} - {{index}}</li></ul></div><script src="../lib/vue.js"></script><script>const app = Vue.createApp({// data: option apidata() {return {message: "Hello Vue",movies: [],info: { name: "daxia", age: 18, height: 1.88 },}},})app.mount("#app")</script></body>
</html>

(3)遍历字符串

 

(4)遍历数字

 

三、数组更新检测

 我们上代码~

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><div id="app"><ul><li v-for="item in names">{{ item }}</li></ul><button @click="changeArray">修改数组</button></div><script src="../lib/vue.js"></script><script>const app = Vue.createApp({// data: option apidata() {return {names: ["abc", "cba", "nba", "aaa", "ccc"],}},methods: {changeArray() {// 1. 直接将数组修改为一个新的数组// this.names = ["why", "kobe"]// 2. 通过一些数组的方法,修改数组中的元素// this.names.push("why")// this.names.pop()// 索引,删除元素的个数(添加的话就是写0),// this.names.splice(2, 1, "why")// 排序// this.names.sort()// 反转this.names.reverse()},},})app.mount("#app")</script></body>
</html>

注意:不修改原数组的方法是不能侦听(watch)

// 3. 不修改原数组的方法是不能侦听(watch)
const newNames = this.names.map((item) => item + "why")
this.names = newNames

 

四、v-for的key属性

 

(1) 认识VNode

我们先来解释一下VNode的概念:

  • 因为目前我们还没有比较完整的学习组件的概念,所以目前我们先理解HTML元素创建出来的VNode。
  • VNode的全称Virtual Node,也就是虚拟节点
  • 事实上,无论是组件还是元素,它们最终在Vue中表示出来的都是一个个VNode;
  • VNode的本质是一个JavaScript的对象;

 

 

 我们先来理解一下,现在id=app的div元素,是不是相当于模板,以前我们是写在下面的,现在写在了上面。

vue并不会根据你写的h2,直接去给你创建一个h2元素。如果直接给你#app.append(h2元素),追加了h2元素的话, 那此时不就是真实DOM的h2元素。

他会在生成真实DOM的h2元素之前,先生成一个VNode。

那VNode到底是一个什么东西呢?

答:VNode的本质是一个JavaScript的对象。他直接用一个JavaScript对象把他表现出来了,并没有直接给你表现出一个h2元素。

假如说你的模板里面有个div元素,他会先把你这个div元素先做一个解析(源码里其实有专门的一部分代码来解析下面这个div元素的,解析成VNode),解析成啥样子的?就是下方的图。本质上就是一个java Script对象。

 

 我们有了VNode,有直接转化成我们真实DOM里面的元素吗? 答:目前还没有。

当我们有了VNode之后,我们就可以对这个Vnode进行解析了。原来我们创建的元素是div元素,原来我们创建的元素的属性是...等等。最终的话再由我们的VNode转换成真实DOM里面的元素,转换成真实DOM里面的元素之后,我们才能在这是DOM里面看到该元素,在 用户界面才能看到。(先做一个了解,后面看源码)。

(2) 虚拟DOM

有童鞋好奇,为什么非要中间加一个虚拟节点、虚拟DOM这个概念,直接创建真实DOM不好吗?

这里最主要的原因有2个:

1. 如果我们当前有个虚拟DOM,方便他去做diff算法。(在下面第六点会提到)

2. 如果有了虚拟DOM,他方便对我们的代码进行跨平台。

我们可以通过虚拟DOM转换成真实DOM,并且渲染到浏览器上面

我们也可以通过虚拟DOM,解析这个java Script对象结构变成移动端的button/view/image等类似控件,然后渲染到移动端显示出来。

我们还可以通过虚拟DOM渲染到桌面端一些控件。

我们也可以渲染到VR设备。

(3)v-for的key属性的作用

了解了VNode、虚拟DOM和真实DOM的概念之后,我们再来看下v-for的key的属性的作用。

我们来个demo,我们想要在letters里面b和c之间插入一个f怎么做?

如果我们未插入一个f之前,我们已经有了虚拟DOM,然后通过原先的虚拟DOM创建了一个真实DOM。

这个时候我们由中间某一个位置给他插入一个东西的时候,我们思考下有几种做法?

1. 第一种,原来这些节点全部不要了, 我从a开始重新创建一个个节点,然后渲染成真实DOM。(没有必要这么去做,为什么?因为刚才的a节点,b节点没有发生变化。没有必要全部销毁从0开始)

2. 第二种, a b 保留,f替代原来c的位置,后面的都得修改。后面少一个了,就去新建e节点。

这种算法的效率不高,因为这里有很多c后面开始重新需要修改的。(他并不知道上面这个c和下面的这个c可以重复利用。这就是vue没有设置key的情况下的算法。仅在中间插入的时候是这样子,如果是在最后插入的话,是没什么区别的。

3. 第三种, 跟上面第二种的区别就是,我给每一个节点加个key。这样子第二次虚拟DOM的时候,我就能知道第一次虚拟DOM的c,d,e,都是可以重复利用的。

总结:所以 v-for 加key属性的作用就是让vue更快识别出来 两个节点是同一个东西。

没有key的diff算法: 

 

有key的diff算法:

 

  

 


http://www.ppmy.cn/news/47737.html

相关文章

4.17-4.18学习总结

MD5 MD5: 1、压缩性 2、容易计算 3、抗修改性 4、弱抗碰撞 5、强抗碰撞 为什么需要MD5&#xff1f; 存储一些敏感信息的时候&#xff0c;如果不进行加密会出现安全问题。 例如&#xff1a;系统登录的密码&#xff0c;如果数据库中的密码采用明文&#xff0c;一旦数据库泄…

面了十几家公司测试岗,我终于悟了,面试无非就是这些题

测试岗的面试其实都是大同小异的&#xff0c;这里我收集整理了185道高频面试题&#xff0c;希望对在找工作或者准备跳槽的各位小伙伴有所帮助&#xff01; 一. 测试基础 1.如何制定测试计划 参考答案&#xff1a; 测试计划包括测试目标、测试范围、测试环境的说明、测试类型…

vue nextTick原理详解

vue nextTick Vue.nextTick() 是一个方法&#xff0c;用于在下次 DOM 更新循环结束之后执行延迟回调。它的实现原理是利用浏览器的异步任务队列机制&#xff0c;在 tick 时刻将回调函数放入队列中等待执行。在实现上&#xff0c;nextTick 方法会根据当前环境选择不同的底层实现…

DCQCN学习

主要思想 发送端的拥塞控制主要有两种形式&#xff0c;一种是基于发送窗口的&#xff0c;另一种是基于rate的 DCQCN是一种基于rate的CC&#xff0c;并主要由ECN机制实现 初始设置sending rate为max line rate 接下来CC主要分为三个部分 CP(Congestion Point) 交换机 出端…

MySQL数据库系统学习(从入门到精通)

MySQL数据库系统学习 一&#xff0c;了解数据库 1.什么是数据库 英文单词DataBase&#xff0c;简称DB。按照一定格式存储数据的一些文件的组合。 顾名思义&#xff1a;存储数据的仓库&#xff0c;实际上就是一堆文件。这些文件中存储了具有特定格式的数据。 2.什么是SQL S…

转义字符(\)对JavaScript中JSON.parse的影响概述

转义字符(\)对JavaScript中JSON.parse的影响 按照ECMA262第五版中的解释&#xff0c;JSON是一个提供了stringify和parse方法的内置对象&#xff0c;前者用于将js对象转化为符合json标准的字符串&#xff0c;后者将符合json标准的字符串转化为js对象。json标准参考<a href&q…

Java中的序列化与反序列化(一)

1、概述 大家好&#xff0c;我是欧阳方超。今天来看一下Java序列化与反序列化的问题。 2、序列化与反序列化 2.1、序列化与反序列化的概念 在Java中&#xff0c;序列化是将对象转换为可存储或传输的格式&#xff08;一般为字节流&#xff09;的过程&#xff0c;序列化后的字…

为什么网络安全缺口很大,招聘却很少?

2020年我国网络空间安全人才数量缺口超过了140万&#xff0c;就业人数却只有10多万&#xff0c;缺口高达了93%。这里就有人会问了&#xff1a; 1、网络安全行业为什么这么缺人&#xff1f; 2、明明人才那么稀缺&#xff0c;为什么招聘时招安全的人员却没有那么多呢&#xff1…

TensorFlow 2 和 Keras 高级深度学习:6~10

原文&#xff1a;Advanced Deep Learning with TensorFlow 2 and Keras 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 不要担心自己的形象&#x…

C# Lambda表达式

目录 Lambda表达式的语法如下&#xff1a; Lambda表达式的内联特性 Lambda表达式常用的方法 C# Lambda表达式简介 Lambda表达式是C#语言中一种函数式编程的特性&#xff0c;它的主要作用是简化代码和提高代码的可读性。在使用Lambda表达式时&#xff0c;可以通过其内联特性…

【C++STL精讲】stack与queue的基本使用及模拟实现

文章目录 &#x1f490;专栏导读&#x1f490;文章导读&#x1f337;stack是什么&#xff1f;&#x1f337;stack的基本使用&#x1f337;stack的模拟实现&#x1f337;queue是什么&#xff1f;&#x1f337;queue的基本使用&#x1f337;queue的模拟实现 &#x1f490;专栏导读…

SpringBoot起步依赖和自动配置

文章目录 1、起步依赖2、自动配置 1、起步依赖 概念 起步依赖本质上是一个Maven项目对象模型&#xff08;Project Object Model&#xff0c;POM&#xff09;&#xff0c;定义了对其他库的传递依赖&#xff0c;这些东西加在一起支持某一功能。 简单的说&#xff0c;起步依赖就…

iptables表、链、规则

netfilter/iptables&#xff08;也就是常说的iptables&#xff09;组成Linux平台下的包过滤防火墙&#xff0c;具有完成封包过滤、封包重定向和网络地址转换&#xff08;NAT&#xff09;等功能。 netfilter是Linux 核心中一个通用架构&#xff0c;它提供了一系列的"表&quo…

手敲Mybatis(九)-结果集处理器

1.前言-背景介绍 上节我们处理了参数处理器&#xff0c;本节我们处理结果集处理器&#xff0c;之前我们写了一个DefaultResultSetHandler&#xff0c;我们把返回结果获取对象&#xff0c;填充值什么的写到了一起&#xff0c;流程没有进行解耦&#xff0c;并且只接收了Object的…

信息系统项目管理师-项目范围管理

1.过程 1.1 规划范围管理 为了记录如何定义、确认和控制项目范围及产品范围&#xff0c;而创建范围管理计划的过程。 1.2 收集需求 为实现目标而确定、记录并管理项目干系人的需要和需求的过程。 1.3 定义范围 制定项目和产品详细描述的过程。 1.4 创建WBS&#xff08;工作分解…

数据库备份shell脚本

文章目录 数据库备份shell脚本变量定义FTP 变量定义函数定义主逻辑 数据库备份shell脚本 # var bak_cmd"--userbakup --password123456 --socket/tmp/mysql.sock --no-timestamp" full_dir"/db/full_date %F" incr_dir"/db/incr_date %F" info&…

Kotlin 1.6.0 的新特性

1、稳定版对于枚举、密封类与布尔值主语穷尽 when 语句 一个详尽的when语句包含了所有主题可能的类型或值的分支&#xff0c;或者对于一些类型包含一个else分支。它覆盖了所有可能的情况&#xff0c;使代码更加安全。 即将禁止非详尽的when语句&#xff0c;以使行为与when表达…

多模态之论文笔记ViLT

文章目录 ViLT: Vision-and-Language Transformer Without Convolution or Region Supervision一. 简介1.1 摘要1.2 文本编码器&#xff0c;图像编码器&#xff0c;特征交互复杂度分析1.2 特征交互方式分析1.3 图像特征提取分析 二. 方法 Vision-and-Language Transformer2.1.方…

Docker Desktop使用PostgreSql配合PGAdmin的使用

在看此教程之前&#xff0c;请先下载安装Docker Desktop 安装成功可以查看版本 然后拉取postgresql的镜像&#xff1a;docker pull postgres:14.2 版本可以网上找一个版本&#xff0c;我的不是最新的 发现会报一个问题 no matching manifest for windows/amd64 10.0.19045 i…

R语言贝叶斯方法在生态环境领域中的应用

贝叶斯统计已经被广泛应用到物理学、生态学、心理学、计算机、哲学等各个学术领域&#xff0c;其火爆程度已经跨越了学术圈&#xff0c;如促使其自成统计江湖一派的贝叶斯定理在热播美剧《The Big Bang Theory》中都要秀一把。贝叶斯统计学即贝叶斯学派是一门基本思想与传统基于…