乐趣区

关于vue.js:前端二面经典vue面试题总结

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 函数渲染
失败

退出移动版