前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >vue-生命周期 源码

vue-生命周期 源码

作者头像
用户3258338
发布2019-10-08 15:53:32
4370
发布2019-10-08 15:53:32
举报
文章被收录于专栏:女程序员的日常_Lin

人生是场马拉松~


生命周期的过程就是vue实例从创建到销毁的过程。在这个过程中提供了一些钩子函数用于让用户自定义一些方法。

vue生命周期:

  • 创建vue实例
  • 通过template编译出的虚拟DOM挂载到真实的DOM
  • DOM的update
  • 销毁

执行生命周期钩子函数是怎么的呢?

执行生命周期的钩子函数最终都是调用callHook函数:

代码语言:javascript
复制
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参数,获取到options的某个属性,得到的是一个数组,然后以vm为上下文,分表调用数组中的函数。

vue合并options的过程中,各个生命周期的调用函数也会合并到options中。并且是个数组。

beforeCreate & created


beforeCreate和created 都是在实例vue的过程中执行的:

代码语言:javascript
复制
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')
  // ...
}

从以上源码可以看出beforeCreate和created分别在initState执行前后。所以在beforeCreate中不能使用date中定义的值,也不能用methods中定义的方法,因为initState是初始化prop、data、computed、watch等属性。

beforeMounted & mounted


beforeMounted和mounted分别表示DOM挂载之前和之后。执行在mountComponent函数中:

代码语言:javascript
复制
export function mountComponent (
  vm: Component,
  el: ?Element,
  hydrating?: boolean
): Component {
  vm.$el = el
  // ...
  callHook(vm, 'beforeMount')

  let updateComponent
  /* istanbul ignore if */
  if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
    updateComponent = () => {
      const name = vm._name
      const id = vm._uid
      const startTag = `vue-perf-start:${id}`
      const endTag = `vue-perf-end:${id}`

      mark(startTag)
      const vnode = vm._render()
      mark(endTag)
      measure(`vue ${name} render`, startTag, endTag)

      mark(startTag)
      vm._update(vnode, hydrating)
      mark(endTag)
      measure(`vue ${name} patch`, startTag, endTag)
    }
  } else {
    updateComponent = () => {
      vm._update(vm._render(), hydrating)
    }
  }

  new Watcher(vm, updateComponent, noop, {
    before () {
      if (vm._isMounted) {
        callHook(vm, 'beforeUpdate')
      }
    }
  }, true /* isRenderWatcher */)
  hydrating = false

if (vm.$vnode == null) {
    vm._isMounted = true
    callHook(vm, 'mounted')
  }
  return vm
}

从以上可以看出beforeMount 和mounted分别在vm.render的前后执行

愿我们有能力不向生活缴械投降---Lin

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 女程序员的日常 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档