vue的实现八股

双向绑定原理

Vue的双向绑定原理是通过数据劫持观察者模式实现的。

vue使用了响应式的对象,即当数据发生改变的时候,视图也会随之改变

数据劫持

vue2使用了object.definedproperty对数据的每个属性进行劫持,从而逐一对每个属性进行set或者get操作,对于一些动态操作和数组操作需要额外的处理

vue3使用了proxy来绑定整个对象,会拦截对象的每个新增,删除等操作,更加的快捷。

vue会绑定一个watcher对象来监听数据的变化,当数据变化时就会进行相应的视图更新

观察者模式(非父子组件之间的通信才是发布订阅模式,注意区别):

vue中有一个watcher对象,用于观察数据的变化以及收集依赖

当vue双向绑定一个数据时,会创建一个watcher对象,并且将watcher对象收集到相关依赖中,当数据发生改变的时候,就会通知所有watch对象,并随着发生相应的改变

vue2数组响应式是怎么实现的呢

vue2中的由于数据劫持是把对象内的每一个属性进行分别绑定,因此当数组元素新增或者删除时,实际变化的是数组length属性,而并没有对每个属性改变,因此数组无法捕获到变化

vue2数组的响应式是通过劫持数组的方法来实现,例如push,pop,shift,sort,reverse等方法,他们在完成对数组操作的同时,还会发生相应通知给watch对象,实现相关的更新操作。

因此在vue2对数组进行操作的时候,尽量使用数组原生方法来操作,如果使用索引对数组进行改变是无法实现响应式的

this.arr[0] = 'd'; // 直接通过索引修改数组元素
this.arr.length = 2; // 直接修改数组的长度
//无法实现响应式

可以使用Vue的$set方法来修改数组元素

$set是Vue中的一个实例方法,用于在响应式对象上添加响应式属性

渲染的过程

1.模板的编译渲染

2.数据的双向绑定

3.创建虚拟dom:vue会根据模板和数据生成虚拟dom,它可以代替真实的dom进行操 作,并将最终结果反应到真实dom上

4.diff算法更新:通过比较vnode的变化,找出需要改变的地方,实现局部的响应式更新

5.最终的结果反应到真实dom上,并且更新相关的节点,随后完成渲染

diff算法过程

diff算法有两个重要策略:

1.比较属性,先对属性比较,属性不同才会更新,同时对子节点进行递归遍历比较

2.key标识,通过唯一的key标识来比较节点

diff算法本质在于,使用双指针对比新旧dom树,然后对子节点进行递归比较:

1.比较根节点,如果根节点不同,直接替换dom树

2.根节点相同则比较他们的子节点

3.比较key值,如果不同,替换。

4.如果key相同,则比较子节点的属性

5.如果key和子节点的属性都相同,则以此类推继续向下递归遍历

注意!即使key相同,属性也可能因为绑定了新的事件或者样式等发生改变,所以key比较完之后,还要对属性进行比较

浏览器为什么不引入虚拟dom

1.不一定所有的业务场景都需要虚拟dom的局部更新功能,一些简单的操作,直接对真实dom进行操作就可以了

2.虚拟dom虽然可以做到更好的视图更新,但是也会带来额外的开销,虚拟dom的创建的和比较,diff算法,都会有额外的性能开销

3.浏览器之间的兼容性问题,不同的浏览器对浏览器引擎的实现可能有所不同,这可能导致在使用虚拟 DOM 时出现一些兼容性问题

vue3的diff算法优化

1.静态标记:对于一些不会变化的静态文本等元素,vue3可以对他们进行标记,对他们进行跳过,减少diff算法的时间

2.模板的优化:对于一些循环渲染,条件渲染,vue3会对他们没有变化的部分进行标记,下次更新对比的时候就可以直接跳过他们

3.fragment支持:vue2的根节点只能有一个,而vue3可以有多个根节点,可以在diff算法避免一些不需要的更新操作,因为有多个根节点,diff算法可以对多个根节点进行比较更新,而vue2只有一个根节点,需要递归到子节点比较

4.静态提升:在编译阶段就对静态内容进行提前创建,避免渲染过程的重复创建,减少运行开销

真实dom是异步更新

为了减少对真实dom的操作引起回流重绘等问题,通过diff算法对虚拟dom进行比较,并且把每个修改操作推入到微任务队列中,通过异步更新的方式,在下一次事件循环中把这些修改一次性应用到真实dom上

通俗的说,就是vue data中的数据更新时,它不会立即去渲染页面,也就是修改页面中的dom,而是先存储起来,如果一个数据被改了很多次,以最后一次修改为准,这就是所谓的异步更新DOM

异步更新可以保证所有的虚拟dom更新完成之后才会应用到真实dom上,从而减少了对真实dom操作

异步更新还确保了所有的虚拟DOM更新完成后才会应用到真实DOM上。这样可以避免因为数据更新导致的页面抖动或者闪烁等问题。保证修改的同时,整个页面的稳定性和一致性。

$nextTick的触发

每次数据变化都会将相应的DOM更新操作推入到异步更新队列中,这些操作会被放入微任务队列中,随后Vue会执行微任务队列中的回调函数,也就是$nextTick的回调函数。

$nextTick 方法可以确保在下一次DOM更新完成之后执行回调函数。虽然DOM的更新并没有立即应用到真实DOM上,但由于 $nextTick 的回调函数是在微任务中执行的,所以此时已经可以获取到更新后的DOM元素的内容了


以下几种异步操作可能会对DOM进行进一步的改变:

  1. AJAX请求:在进行异步的API请求或数据获取时,可能会根据返回的结果再次修改DOM。
  2. 定时器:使用setTimeout或setInterval等方法设置的定时器,可以在一段时间后对DOM进行修改。
  3. 事件监听器:当触发一些事件时,例如点击事件、滚动事件或键盘事件等,可能会导致DOM的改变。
  4. Vue的生命周期钩子函数:在Vue组件的生命周期中,存在一些钩子函数,例如created、mounted等,在这些钩子函数中,可以对DOM进行进一步的操作

promise为什么能实现nextTick呢

因为promise本质也是一个异步任务,他的回调在微任务队列中,和nextTick的执行一样,本质就是有一个延后性,使得真实dom发生改变后可以获取到当前dom元素,因此使用setTimeout()模拟也是同理

Vue 2.x 中使用 setTimeout() 模拟微任务延迟执行存在一定的延迟性,可能不够精确。

在 Vue 3.x 中,Vue 则采用了原生的 Promise 和 queueMicrotask() 来实现更精确的微任务延迟执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/296.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【报错】Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)

在你检查完没有内存溢出等各种各种情况之后,仍然不知道该怎么解决,这里提供一个可能的解决办法。 如果你也用的是Mac M1芯片,在跑numpy的时候出现 Intel MKL Warning; 或在用pytorch训练模型的时候遇到segmentation fault。有可能…

【机器学习300问】75、如何理解深度学习中Dropout正则化技术?

一、Dropout正则化的原理是什么? Dropout(随机失活)正则化是一种用于减少神经网络中过拟合现象的技术。Dropout正则化的做法是: 在训练过程中的每次迭代中,随机将网络中的一部分权重临时"丢弃"(即…

Java工具类:压缩图片至指定大小

不好用请移至评论区揍我 原创代码,请勿转载,谢谢! 一、介绍 接收File参数及目标大小,将自动递归压缩至指定大小已增加删除压缩产生的临时文件等逻辑处理传递的原文件将不会执行delete操作,而是在基础上返回压缩后的文件传递文件名示例(xxx.txt),压缩后文件名示例(xxx_…

前端三大件速成 01 HTML

文章目录 一、前端基础知识二、标签1、什么是标签2、标签的属性3、常用标签(1)声明(2)注释(3)html 根标签(3)head标签(4)body标签 三、特殊字符四、其他标签1…

web安全学习笔记(11)

记一下第十五节课的内容。 一、创建MySQL执行函数 我们在function.php中,自定义一个函数: #SQL查询函数 function Qurey($sql) {#连接数据库$db new mysqli(172.20.10.3, liuyan, 123456, liuyan, 3306);#判断是否连接成功if (mysqli_connect_errno(…

redis的数据结构报错

文章目录 redis的数据结构报错Redis使用LocalDateTime报错问题 redis的数据结构报错 Redis使用LocalDateTime报错问题 SpringBoot整合Redis时,使用LocalDate以下报错 org.springframework.data.redis.serializer.SerializationException: Could not read JSON: C…

(八)Pandas窗口数据与数据读写 学习简要笔记 #Python #CDA学习打卡

一. 窗口数据(Window Functions) Pandas提供了窗口函数(Window Functions)用于在数据上执行滑动窗口操作,可以对数据进行滚动计算、滑动统计等操作。需要注意的是,在使用窗口函数时,需要根据实际需求选择合适的窗口大小和窗口函数&#xff0…

大数据------额外插件及技术------Git(完整知识点汇总)

Git 定义 它是分布式版本控制工具,主要用于管理开发过程中的源代码文件(如:Java类、xml文件、html页面等),在软件开发过程中被广泛应用 作用 代码回溯:快速回到某一代码历史版本版本切换:同一个…

Qt解析json格式数据

文章目录 json格式对象格式数组格式 QJsonDocument, QJsonObject,QJsonArray,QJsonValue例一:如何构建QJsonObject和QJsonDocument例二:解析前面的嵌套型json数据 json格式 对象格式 一个对象, 由一个大括号表示: 括号中 描述对象的属性&am…

【嵌入式开发】SecureCRTPortable工具进行串口信息监听打印

SecureCRTPortable工具进行串口信息监听打印 一、什么是SecureCRT二、如何使用SecureCRT进行串口监听1、硬件连接2、驱动安装3、软件连接4、串口连接5、日志设置 近期发现许多小伙伴欠缺SSH工具使用基础,工欲善其事,必先利其器,这里奉上使用教…

股票战法课程之主力的痕迹

文章目录 1. 主力的操作痕迹2. 主力的建仓2.1 建仓的三种方式2.2 建仓的五个特点2.3 建仓的迹象2.4 建仓的成交量特征 1. 主力的操作痕迹 序号痕迹原因1不跟随大盘节奏筹码都在主力手中2突发利空消息,股价不跌反涨主力被套,不希望散户抛盘3很小的成交量…

【Spring】Spring MVC入门

Spring MVC入门 一、什么是Spring Web MVC? 1.1 MVC定义 MVC是Model View Controller的缩写,是一种软件架构的设计模式,将软件系统分为模型、视图、控制器三个部分。 示意图如下: 可以看到,Controller作为一个“粘合剂”处于M…

Go 单元测试之mock接口测试

文章目录 一、gomock 工具介绍二、安装三、使用3.1 指定三个参数3.2 使用命令为接口生成 mock 实现3.3 使用make 命令封装处理mock 四、接口单元测试步骤三、小黄书Service层单元测试四、flags五、打桩(stub)参数 六、总结6.1 测试用例定义6.2 设计测试用…

linux环境下创建网口聚合实例

Linux的网口聚合(网口绑定、bonding)技术是一种通过多个网络接口聚合来提供网络冗余和/或增加网络带宽的方法,为提供网络稳定性、带宽、性能非常有利工具,常见的网口聚合可以支持不同工作模式 mode0 (balance-rr):轮询…

详细分析Mysql常用函数(附Demo)

目录 前言1. 聚合函数2. 字符串函数3. 日期函数4. 条件函数5. 数值函数6. 类型转换函数 前言 由于实战中经常运用,索性来一个总结文 创建一个名为 employees 的表,包含以下字段: employee_id:员工ID,整数类型 first…

Linux的图形资源及指令

一、火车 1.切换到超级用户 su 2.下载资源 yum install -y sl 3.输入指令 sl,得到火车图形 如果没有得到该图形,就将2处改为yum install -y epel-release。 二、Linux的logo 1.在超级用户模式下下载资源 yum install -y linux_logo 2.输…

Eureka删除失效服务

方式一: curl -X DELETE http://主节点IP:1200/eureka/apps/LY-SM-BPM-EXPANSION-SVC/6dc2f49bca12:ly-sm-bpm-expansion-svc:6932 如果方式一过一会还会出现的话,采用 方式二: curl -X PUT http://主节点IP:1200/eureka/apps/LY-SM-BPM-…

物联网(iot)深度解析——FMEA软件

物联网即IoT,是指通过各种信息传感器、射频识别技术、全球定位系统、红外感应器、激光扫描器等各种装置与技术,实时采集任何需要监控、连接、互动的物体或过程,采集其声、光、热、电、力学、化学、生物、位置等各种需要的信息,通过…

C语言——字符函数与字符串函数

正文开始:在编程过程中,我们经常要处理字符和字符串,为了方便操作字符和字符串,C语⾔标准库中提供了 一系列库函数,接下来我们就学习⼀下这些函数。 1. 字符分类函数 C语⾔中有⼀系列的函数是专门做字符分类的&#…

android远程更新下载apk

最近业务有涉及到&#xff0c;奈何是个app代码小白&#xff0c;遂记录一下 一&#xff1a;AndroidManifest.xml文件配置 application标签里面加上 android:networkSecurityConfig"xml/network_config" <!-- app下载更新配置--> <uses-permission andr…