Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue 源码阅读【3】—— 生命周期 #58

Open
amandakelake opened this issue Oct 12, 2018 · 0 comments
Open

Vue 源码阅读【3】—— 生命周期 #58

amandakelake opened this issue Oct 12, 2018 · 0 comments
Labels

Comments

@amandakelake
Copy link
Owner

amandakelake commented Oct 12, 2018

源码中最终执行生命周期的函数都是调用 callHook 方法,它的定义在 src/core/instance/lifecycle

export function callHook (vm: Component, hook: string) {
  // #7573 disable dep collection when invoking lifecycle hooks
  pushTarget()
  const handlers = vm.$options[hook]
  if (handlers) {
    for (let i = 0, j = handlers.length; i < j; i++) {
      try {
        handlers[i].call(vm)
      } catch (e) {
        handleError(e, vm, `${hook} hook`)
      }
    }
  }
  if (vm._hasHookEvent) {
    vm.$emit('hook:' + hook)
  }
  popTarget()
}

根据传入的字符串hook,去拿到 vm.$options[hook] 对应的回调函数数组,然后遍历执行,执行的时候把 vm 作为函数执行的上下文

beforeCreate & created

beforeCreatecreated 函数都是在实例化 Vue 的阶段,在 _init 方法中执行的,它的定义在 src/core/instance/init.js

Vue.prototype._init = function (options?: Object) {
  // ...
  initLifecycle(vm)
  initEvents(vm)
  initRender(vm)
  callHook(vm, 'beforeCreate')
  initInjections(vm) // resolve injections before data/props
  initState(vm)
  initProvide(vm) // resolve provide after data/props
  callHook(vm, 'created')
  // ...
}

这两个生命钩子定义在initState(vm)前后
initState(vm)的作用是初始化props、data、methods、watch、computed 等属性
所以beforeCreate钩子中是无法读取到上述的属性的

同时这里也还没有渲染DOM,所以这两个生命钩子都不能访问DOM

如果想请求数据,这两个钩子都是OK的
不过如果要跟data、props里面的数据交互,就要在created

beforeMount & mounted

beforeMount发生在DOM挂载之前,调用函数是mountComponent,定义在src/core/instance/lifecycle.js

beforeDestroy & destroyed

beforeDestroy 钩子函数的执行时机是在 $destroy 函数执行最开始的地方,接着执行了一系列的销毁动作,包括从 parent 的 $children 中删掉自身,删除 watcher,当前渲染的 VNode 执行销毁钩子函数等,执行完毕后再调用 destroy 钩子函数。

在 $destroy 的执行过程中,它又会执行 vm.patch(vm._vnode, null) 触发它子组件的销毁钩子函数,这样一层层的递归调用,所以 destroy 钩子函数执行顺序是先子后父,和 mounted 过程一样。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant