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 地址

相關文章
相關標籤/搜索