vue 生命周期梳理

前言

在使用vue开发过程当中常常会接触到生命周期的问题,但对于每一个钩子函数都作了什么,应用场景比较模糊,但愿经过此次梳理让本身清楚一些。初次写文章,有不对的地方还望各位多多指正!vue

1. vue实例化过程

从vue实例化开始分析,咱们经过new Vue来实例化来查看一下源码 在 src/core/instance/init.js 中定义 使用vscode的小伙伴推荐使用Search node_modules插件查找node_modules中的插件方便多了,妈妈不再用担忧我迷路了node

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')

  /* istanbul ignore if */
  if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
    vm._name = formatComponentName(vm, false)
    mark(endTag)
    measure(`vue ${vm._name} init`, startTag, endTag)
  }

  if (vm.$options.el) {
    vm.$mount(vm.$options.el)
  }
}
复制代码

Vue 初始化主要就干了几件事情,合并配置,初始化生命周期,初始化事件中心,初始化渲染,初始化 data、props、computed、watcher 等等,vue 把不一样的功能逻辑拆成一些单独的函数执行。git

咱们关注到,在这个过程当中插入钩子函数,提供给开发者调用的机会。在初始化的最后,检测到若是有 el 属性,则调用 vm.$mount 方法挂载 vm,挂载的目标就是把模板渲染成最终的 DOM。github

2.生命周期钩子

  1. 生命周期钩子自动绑定this到实例上,所以你能够经过this.操做访问到数据和方法。注意不能使用箭头函数例以下方代码,由于箭头函数绑定外层的this会一直往上找。
created:()=>{// ...代码}
复制代码
  1. 下面用在各个生命周期中打印下el,data,dom节点
export default {
  name: 'App',
  data() {
    return {
      title: '标题'
    }
  },
   methods: {
    onDestoryClick() {
      this.$destroy()
    }
  },
  beforeCreate() {
    console.log(
      `\n\nbeforeCreate打头\n$el    :${this.$el}\n$data     :${JSON.stringify(
        this.$data
      )}\n$refs.head   :${JSON.stringify(
        this.$refs.head
      )}\nbeforeCreate结尾\n\n`
    )
    console.log(this.$vnode)
  },
  created() {
    console.log(
      `\n\ncreated打头\n$el    :${this.$el}\n$data     :${JSON.stringify(
        this.$data
      )}\n$refs.head   :${JSON.stringify(this.$refs.head)}\ncreated结尾\n\n`
    )
    console.log(this.$vnode)
  },
  beforeMount() {
    console.log(
      `\n\nbeforeMount打头\n$el    :${this.$el}\n$data     :${JSON.stringify(
        this.$data
      )}\n$refs.head   :${JSON.stringify(this.$refs.head)}\nbeforeMount结尾\n\n`
    )
    console.log(this.$vnode)
  },
  mounted() {
    console.log(
      `\n\nmounted打头\n$el    :${this.$el}\n$data     :${JSON.stringify(
        this.$data
      )}\n$refs.head   :${JSON.stringify(this.$refs.head)}\nmounted结尾\n\n`
    )
    console.log(this.$vnode)
  }
}
复制代码

结果图
能够发现

  1. beforeCreate中拿不到任何数据,它在实例初始化以后,数据观测 (data observer) 和 event/watcher 事件配置以前被调用。ajax

  2. created中已经能够拿到data中的数据了,可是dom尚未挂载。会判断有无el,若是没有el则中止后面的模板挂载。api

    在实例建立完成后被当即调用。在这一步,实例已完成如下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。浏览器

    使用场景:ajax请求和页面初始化bash

  3. beforeMount 和 created 拿到的数据相同 在挂载开始以前被调用:相关的 render 函数首次被调用。dom

  4. mounted中el被建立dom已经更新,vue实例对象中有template参数选项,则将其做为模板编译成render函数,编译优先级render函数选项 > template选项ide

    使用场景:经常使用于获取VNode信息和操做,ajax请求

    注意 mounted 不会承诺全部的子组件也都一块儿被挂载。若是你但愿等到整个视图都渲染完毕,能够用 vm.$nextTick 替换掉 mounted

  5. 因为beforeUpdate和updated使用的比较少,通常用计算属性和watch代替因此在此不在说明

  6. destroyed Vue 实例销毁后调用。调用后,Vue 实例指示的全部东西都会解绑定,全部的事件监听器会被移除,全部的子实例也会被销毁。

客户端渲染过程

  1. 处理 HTML 标记并构建 DOM 树。
  2. 处理 CSS 标记并构建 CSSOM 树。
  3. 将 DOM 与 CSSOM 合并成一个渲染树。
  4. 根据渲染树来布局,以计算每一个节点的几何信息。
  5. 将各个节点绘制到屏幕上。

参考资料

  1. vue.js
  2. 浏览器渲染过程

代码

github 地址

相关文章
相关标签/搜索