對vue生命週期/鉤子函數詳解

對於實現頁面邏輯交互等效果,咱們必須知曉vue的生命週期,才能愉快的玩耍,知道咱們寫的東西應該掛載到哪裏,vue官方給出的api講解的那叫一個簡單啊,以下:vue

全部的生命週期鉤子自動綁定this上下文到實例中,所以你能夠訪問數據,對屬性和方法進行運算。這意味着你不能使用箭頭函數來定義一個生命週期方法(例如created: () => this.fetchTodos())。這是由於箭頭函數綁定了父上下文,所以this與你期待的 Vue 實例不一樣,this.fetchTodos的行爲未定義。vue-router

下面附加一張生命週期圖示api

 

 

  生命週期

beforeCreate   初始化以前
created  建立完成
beforeMount   掛載更新前
mounted   被建立
beforeUpdat   數據更新前
updated   被更新後
beforeDestroy   銷燬以前
destroyed   銷燬以後dom

 

 

詳解:

  1. beforeCreate
    官方說明:在實例初始化以後,數據觀測(data observer) 和 event/watcher 事件配置以前被調用。
    解釋:這個時期,this變量還不能使用,在data下的數據,和methods下的方法,watcher中的事件都不能得到到;異步

    beforeCreate() {
       console.log(this.page); // undefined
       console.log{this.showPage); // undefined
     },
     data() {
       return {
         page: 123
       }
     },
     methods: {
       showPage() {
         console.log(this.page);
       }
     }
  2. created
    官方說明:實例已經建立完成以後被調用。在這一步,實例已完成如下的配置:數據觀測(data observer),屬性和方法的運算, watch/event 事件回調。然而,掛載階段還沒開始,$el 屬性目前不可見。
    解釋說明: 這個時候能夠操做vue實例中的數據和各類方法,可是還不能對"dom"節點進行操做;函數

    created() {
       console.log(this.page); // 123
       console.log{this.showPage); // ...
       $('select').select2(); // jQuery插件須要操做相關dom,不會起做用
     },
     data() {
       return {
         page: 123
       }
     },
     methods: {
       showPage() {
         console.log(this.page);
       }
     }
  3. beforeMounte
    官方說明:在掛載開始以前被調用:相關的 render 函數首次被調用。fetch

  4. mounted
    官方說明:el 被新建立的 vm.$el 替換,並掛載到實例上去以後調用該鉤子。若是root實例掛載了一個文檔內元素,當 mounted 被調用時 vm.$el 也在文檔內。
    解釋說明:掛載完畢,這時dom節點被渲染到文檔內,一些須要dom的操做在此時才能正常進行this

    mounted() {
       $('select').select2(); // jQuery插件能夠正常使用
     },

這時初始化插件沒有問題,插件能正常運行,可是這並不表明萬事大吉;下面思考一個問題:url

select2
select2

圖中的selectoption都是經過異步請求獲得的,而後經過v-for渲染進去,到此一切看起來很正常。還有一個需求是當頁面刷新後要保留上次一查詢的條件。我經過vue-router來給select指定一個默認選項;spa

<template v-for='(item, index) in agentList.name' >
     <option v-if='item == name' :key='index' selected :value="item">{{item}}</option>
      <option v-else :key='index' :value="item">{{item}}</option>
   </template>

那麼問題就來了,option的得到是一個異步請求,那這個請求完成的時刻和mounted的順序是什麼?若是mounted在請求成功以前執行,那將很遺憾——默認選項會設置失敗

option有默認效果的是130,select中的值仍是保持所有
option有默認效果的是130,select中的值仍是保持所有

何時執行$('select').select2(),是解決這個問題的關鍵。你們確定猜到了,mounted的確是在請求成功以前執行的,因此這時的辦法就是將$('select').select2()的執行放到請求成功的回調裏執行:

$.getJSON(urls.agentAndCity, {pageType: this.pageType}, (res) => {
    const a = this.agentList,
    d = res.data;
    a.id = d.orgIds;
    a.name = d.orgNames;
    a.city = d.cityMap;
    $('select').select2();
  });

本覺得這樣就完美解決了,可是發現仍是會出現和上圖同樣的效果;如何是好?這時輪到vm.$nextTick登場了:
說明: 將回調延遲到下次 DOM 更新循環以後執行。在修改數據以後當即使用它,而後等待 DOM 更新。
官方示例代碼:

new Vue({
      // ...
      methods: {
      // ...
      example: function () {
      // 修改數據
      this.message = 'changed'
      // DOM 尚未更新
        this.$nextTick(function () {
          // DOM 如今更新了
          // `this` 綁定到當前實例
          this.doSomethingElse()
        })
      }
    }
  })

因此個人解決辦法以下:

$.getJSON(urls.agentAndCity, {pageType: this.pageType}, (res) => {
    const a = this.agentList,
    d = res.data;
    a.id = d.orgIds;
    a.name = d.orgNames;
    a.city = d.cityMap;
    this.$nextTick(() => {
      $('select').select2();
    });
  });

至此這個問題纔算比較滿意的解決

相關文章
相關標籤/搜索