背景
最近在学习vu2的源码,上一篇总结了vue响应式的核心原理。本篇主要是把vue的声明周期和和源码中的位置做对应,方便后续学习。
vue的生命周期
1. new Vue
function Vue (options) {
this._init(options)
}
// new Vue();相当于执行了实例上的_init方法
- this._init方法在那里设置的?
// initMixin(Vue)中设置。文件位置:src\core\instance\init.js
export function initMixin (Vue: Class<Component>) {
Vue.prototype._init = function (options?: Object) {
...省略代码
}
}
- _init方法做了哪些初始化操作(给实例上设置方法或者属性)
initLifecycle(vm) // 给实例上添加声明周期相关的属性
initEvents(vm) // 自定义组件事件监听
initRender(vm) // 插槽处理
callHook(vm, 'beforeCreate')
// ---------------------beforeCreated----------------------
initInjections(vm) // vm.$options.inject
initState(vm) // data/props/methods/computed/watch
initProvide(vm) // vm.$options.provide
callHook(vm, 'created')
// ----------------------created------------------------------
2. initEvents&lifecycle---initLifecycle
// 文件位置:src\core\instance\lifecycle.js
vm.$parent = parent
vm.$root = parent ? parent.$root : vm
vm.$children = []
vm.$refs = {}
vm._watcher = null
vm._inactive = null
vm._directInactive = false
vm._isMounted = false
vm._isDestroyed = false
vm._isBeingDestroyed = false
2. initEvents&lifecycle---initEvents自定组件事件
3. initInjections&reactive
// 初始化参数和代理设置
initInjections(vm) // vm.$options.inject
initState(vm) // data/props/methods/computed/watch
initProvide(vm) // vm.$options.provide
4. mounted阶段
// this._init方法最后会调用$mount方法,执行自动挂载
if (vm.$options.el) {
vm.$mount(vm.$options.el)
}
- vm.$mont方法在哪里定义
// src\platforms\web\entry-runtime-with-compiler.js
const mount = Vue.prototype.$mount // 重写mount方法为不同的平台做适配
Vue.prototype.$mount = function (
el ? : string | Element,
hydrating ? : boolean): Component {
el = el && query(el)
const options = this.$options
if (el) {
template = getOuterHTML(el)
}
if (template) {
const {
render,
staticRenderFns
} = compileToFunctions(template, {
outputSourceRange: process.env.NODE_ENV !== 'production',
shouldDecodeNewlines,
shouldDecodeNewlinesForHref,
delimiters: options.delimiters,
comments: options.comments
}, this)
options.render = render
options.staticRenderFns = staticRenderFns
}
return mount.call(this, el, hydrating)
}
// 被重写的$mount方法
// src\platforms\web\runtime\index.js
Vue.prototype.$mount = function (
el?: string | Element,
hydrating?: boolean
): Component {
el = el && inBrowser ? query(el) : undefined
return mountComponent(this, el, hydrating)
}
- 最后执行的mountComponent做了哪些操作
function mountComponent(){
callHook(vm, 'beforeMount')
updateComponent = () => {
// 首先执行render =》 vdom
vm._update(vm._render(), hydrating)
}
new Watcher(vm, updateComponent, noop, {
before () {
if (vm._isMounted && !vm._isDestroyed) {
callHook(vm, 'beforeUpdate')
}
}
}, true)
}
- new Watcher把当前的vm的undataComponent方法---更新的方法加入到vm的依赖数组,完成了依赖的收集。