写点什么

new Vue 的时候到底做了什么

作者:bb_xiaxia1998
  • 2022 年 9 月 30 日
    浙江
  • 本文字数:1388 字

    阅读完需:约 5 分钟

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的引用,//等等属性 }] }
复制代码



更多面试题解答参见 前端vue面试题详细解答

什么是 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 函数渲染

用户头像

bb_xiaxia1998

关注

还未添加个人签名 2022.09.01 加入

还未添加个人简介

评论

发布
暂无评论
new Vue的时候到底做了什么_Vue_bb_xiaxia1998_InfoQ写作社区