vue面试之new Vue的时候到底做了什么
作者:风度翩翩的红金鱼 发布时间:2024-06-05 15:31:27
Vue加载流程
1.初始化的第一阶段是Vue实例也就是vm对象创建前后:首先Vue进行生命周期,事件初始化发生在beforeCreate生命周期函数前,然后进行数据监测和数据代理的初始化,也就是创建vm对象的过程,当vm对象创建完成就可以通过vm对象访问到劫持的数据,比如data中的数据,methods中的方法等。然后Vue调用内部的render函数开始解析模板将其解析为一个JS对象也即在内存中生成虚拟DOM也就是Vnode对象。第二阶段是vm对象挂载前后:挂载完成前页面呈现的是未经过Vue编译的DOM结构,所有对DOM的操作最终都不会生效。挂载前首先将内存中的Vnode转换为真实DOM插入页面,此时完成挂载。页面中呈现的就是经过Vue编译的DOM结构,至此初始化过程结束。
2.开启订阅消息也就是数据劫持代理监听,其实就是写了一个watcher函数去监听数据的改变,发送网络请求,绑定自定义事件等初始化操作。当数据发生变化以后即状态变更的时候,会重新构造新的Vnode对象。然后用新的Vnode对象和旧的Vnode对象进行差异比较也就是DIFF算法,然后把差异应用到旧的Vnode对象所构建的真正的DOM树上这个过程就是patch,视图就更新了
每一个组件在加载时都会调用Vue内部的render函数把该组件的tamplate选项的模板解析为一个JS对象,这个对象和DOM节点对象结构一样,然后是数据劫持代理监听,当数据发生变化以后,将旧Vnode对象和生成的新Vnode对象比较差异然后更新DOM
Vnode: {
tag:"",
id:,
name:"Box",
$el:真实页面上的DOM的引用,
//等等属性
chiren:[
{ tag:"",
id:,
name:"Box2",
$el:真实页面上的DOM的引用,
//等等属性 },
{
tag:"",
id:,
name:"Box3",
$el:真实页面上的DOM的引用,
//等等属性 }
] }
什么是DIFF
diff算法是一种对比算法。对比两者是旧虚拟DOM和新虚拟DOM,对比出是哪个虚拟节点更改了,找出这个虚拟节点,并只更新这个虚拟节点所对应的真实节点,而不用更新其他数据没发生改变的节点,实现精准地更新真实DOM,进而提高效率
其有两个特点:
比较只会在同层级进行, 不会跨层级比较
在diff比较的过程中,循环从两边向中间比较
DIFF算法的过程:
当数据发生改变时,订阅者
watcher
就会调用patch
给真实的DOM
打补丁通过
isSameVnode
进行判断,相同则调用patchVnode
方法patchVnode
做了以下操作:找到对应的真实
dom
,称为el
如果都有都有文本节点且不相等,将
el
文本节点设置为Vnode
的文本节点如果
oldVnode
有子节点而VNode
没有,则删除el
子节点如果
oldVnode
没有子节点而VNode
有,则将VNode
的子节点真实化后添加到el
如果两者都有子节点,则执行
updateChildren
函数比较子节点updateChildren
主要做了以下操作:设置新旧
VNode
的头尾指针新旧头尾指针进行比较,循环向中间靠拢,根据情况调用
patchVnode
进行patch
重复流程、调用createElem
创建一个新节点,从哈希表寻找key
一致的VNode
节点再分情况操作
参考 前端进阶面试题详细解答
关于Vue中el,template,render,$mount的渲染
渲染根节点:
先判断有无el属性,有的话直接获取el根节点,没有的话调用$mount去获取根节点。
渲染模板:
有render:这时候优先执行render函数,render优先级 > template。
无render:有template时拿template去解析成render函数的所需的格式,并使用调用render函数渲染。无template时拿el根节点的outerHTML去解析成render函数的所需的格式,并使用调用render函数渲染
渲染的方式:无论什么情况,最后都统一是要使用render函数渲染
来源:https://segmentfault.com/a/1190000043533072


猜你喜欢
- 什么是可变/不可变对象不可变对象,该对象所指向的内存中的值不能被改变。当改变某个变量时候,由于其所指的值不能被改变,相当于把原来的值复制一份
- 本文实例讲述了JS基于封装函数实现的表格分页。分享给大家供大家参考,具体如下:HTML代码:<html><head>
- 通常来说,php中总是只获取最后一个复选框的值,那么如何才能获取所有复选框的值?解决办法如下:form表单的部分代码如下:<input
- 1.字符串定义# coding:utf-8if __name__ == '__main__': &
- 方式1:静态获取,通过直接解析checkpoint文件获取变量名及变量值通过reader = tf.train.NewCheckpointR
- 1. Python中lib、package和module的关系module:以.py为结尾的文件都是模块。package:就是一个带__in
- 本文实例分析了JS重载实现方法。分享给大家供大家参考,具体如下:重载是面向对象语言里很重要的一个特性,JS中没有真正的重载,是模拟出来的(因
- JQuery,mootools,Ext等类库在这部分实现得非常艰辛,盘根错节地动用一大堆方法,因此想把这部分抠出来难度很大。深入研究它们的实
- <script language="JavaScript"> //得到字符总数function getCha
- 代码: (使用os.listdir) import osdef ListFilesToTxt(dir,file,wildcard,recur
- 1. Vue 路由权限控制一般有2种方法a、路由元信息(meta)b、动态加载菜单和路由(addRoutes)2 路由元信息(meta)来进
- 在Pydev能正常执行的脚本,在导出后在命令行执行,通常会报自己写的包导入时找不到。一:报错原因在PyDev中,test.py 中导入Tes
- prompt命令可以在mysql提示符中显示当前用户、数据库、时间等信息mysql -uroot -p --prompt="\\u
- 本文实例讲述了JavaScript函数参数使用带参数名的方式赋值传入的方法。分享给大家供大家参考。具体分析如下:这里其实就是在给函数传递参数
- 首先说明一下SQL Server内存占用由哪几部分组成。SQL Server占用的内存主要由三部分组成:数据缓存(Data Buffer)、
- 开启慢查询日志在项目中我们会经常遇到慢查询,当我们遇到慢查询的时候一般都要开启慢查询日志,并且分析慢查询日志,找到慢sql,然后用expla
- 随着网络技术的不断发展,网络应用已经渗透到人类社会的各个角落。作为网络世界的支撑点的网站,更是人们关注的热点:政府利用网站宣传自己的施政纲领
- 作为胶水语言,Python可以很方便的执行系统命令,Python3中常用的执行操作系统命令有os.system()、os.popen()、s
- 网上关于这方面的文章有很多,重复的东西本文不再赘述,仅提供思路,并解释一些其他文章讲述模糊的地方。 1、使用meta标签,这也是普
- 为了防止采集,我试过各种方法,绝大多数方法是“ * 剑”---防止了采集,也影响了搜索引擎收录,实在不爽!一天本人忽发奇想:何不