1. new Vue()
new Vue() 后, Vue 会调用 _init 函数进行初始化,也就是这里的 init 过程,它会初始化生命周期、事件、 props、 methods、 data、 computed 与 watch 等。其中最重要的是通过 Object.defineProperty 设置 setter 与 getter 函数,用来实现「响应式」以及「依赖收集」
2. compile 三个阶段
parse:正则等方式解析 template 模板中的指令、class、style等数据,形成AST(抽象语法树)。
optimize:标记 static 静态节点—更新界面时,会有一个 patch 的过程, diff 算法会直接跳过静态节点
generate:将 AST 转化成 render function 字符串的过程,得到结果是 render 的字符串以及 staticRenderFns 字符串
在经历过 parse、optimize 与 generate 这三个阶段以后,组件中就会存在渲染 VNode 所需的 render function 了,用getter函数进行依赖收集
3. 响应式
对象被读取的时候会执行 getter 函数,而在当被赋值的时候会执行 setter 函数
依赖收集的目的是将观察者 Watcher 对象存放到当前闭包中的订阅者Dep 的 subs 中
值改变 => 触发setter => 通知依赖收集的每一个watch => patch到需要改变的那个watcher => 调用update来更新视图
响应式系统: Object.defineProperty(obj, prop, descriptor)
descriptor: enumerable configurable get set
1 | function cb() { |
4. Virtual DOM
render function() (VNode 节点)作为基础的树,用对象属性来描述节点,实际上它只是一层对真实 DOM 的抽象
5. 更新视图
将新的 VNode 与旧的 VNode 一起传入 patch 进行比较,经过 diff 算法得出它们的「差异」。最后我们只需要将这些「差异」的对应 DOM 进行修改即可
1 | //订阅者 Dep |
6.Vuex
dispatch => actions(…mapActions({}))
commit => mutations (mutation-types.js SOME_MUTATION{} …mapMutations([]))
mutate => State(…mapState({}))
getters(…mapGetters([]))