1 Vue 是一个 Class 是一个构造函数,
在实例化后,Vue 会调用_init
函数来进行初始化,
他会初始化生命周期、事件、props、methods、data、computed 与 watch 等。
在初始化过程中会通过 Object.defineProperty 来设置 stter 与 getter 函数,用来实现【响应式】以及【依赖收集】
依赖收集主要是针对对出现在 template 中的参数(需要更新视图)以及出现在 computed 和 watch 中的参数进行依赖收集。
每一个数据对象都会有一个自已的订阅者集合 Dep,Dep 中存放了 Watcher 观察者对象。
Dep 类有 2 个主要的方法:
1.addSub 增加一个 Watcherd 订阅者到 subs 中
2.notify 通知 Dep 对象中的所有 Watcher 观察者触发更新 update 操作
在对数据进行响应式时:
get 触发时会触发 dep 的 addSub 将当前的 watcher 对象存入 dep 的 subs 中,
set 触发时会触发 dep 的 notify 方法通知所有 watcher 对象 update 操作更新视图
render function 在渲染时,其中的依赖对象都会被读取,触发 get 时的依赖收集
2 初始化后会调用$mount 来挂载组件,如果有 template 还需要进一步编译
3 编译分为 3 个步骤:parse,optimize 与 generate,最终得到 render function
3.1 parse 会用正则等方式将 template 中的模版进行解析生成 AST 树(抽象语法树 abstract syntax tree)
3.2 optimize 通过为静态节点(只有 node.type==3 为文本节点时才是静态节点)做标记,在 patch 的时候跳过这些标记为静态节点的对比,达到优化的目的
3.3 generate 会将 AST 树转为 render function 字符串
4 当触发 watcher 对象的 update 操作时,最终会将产生的新 VNode 节点与老 VNode 进行一个 patch 对比操作,对比出差异后,将差异更新到视图上
vue 中的 diff 算法是通过同层的树节点进行比较而非对树进行逐层搜索遍历的方式,所以时间复杂度只有 O(n)
双指针 diff 算法
5 批量更新策略以及 nextTick