vue 關於生命週期

來源:互聯網
上載者:User

標籤:his   func   date   local   font   javascrip   data   cal   .ajax   

序言:

  1. vue 單組件的生命週期;

  2. vue 父子組件的生命週期;

  3. axios 非同步請求 與 vue 的組件周期;

 

一、vue 每個組件的生命週期

  關於每個組件的生命週期,官方文檔裡也提供了,網上也能搜到各路大神們的相關文章,這裡不贅述,貼一個網址以及簡單總結。

  Vue的生命週期 - 轉自淺白

  簡單總結:

    1.beforeCreate 此時 $el、data 的值都為 undefined ;

    2.created 此時可以拿到 data 中的值,但是 this.$el 任然是 undefined ;

    3.beforeMounte 此時可以列印 this.$el, 但是當中的 {{ data }} 還沒有被替換,this.$el 是虛擬節點;

    4.mounted data,$el 均可以被列印,{{ data }} 也已經被替換成正式的 Dom, vue執行個體被掛載在真實的 dom 樹上;

    5.beforeUpdate/updated ;

    6.beforeDestroy/destroyed;

  一張簡單:

 

 

二、父子組件的生命週期

  在項目中,平時可能更多的是關心單個組件的生命週期。

  最近手頭的一個項目有一個最佳化:入口是一個平台(父系統),在這個父系統中點擊按鈕進入子系統的相應模組,當然,視窗開啟檔案是 _blank,父子系統之間的通訊流程是,vue路由導航守衛根據 cookie 中的 token 設定,cookie 中如過有 token ,正常跳轉,沒有 token ,通過 H5 postMessage() / window.addEventListener(‘message‘, function(event){}, false) 來向父系統擷取 toke, 在回呼函數 function(event){} 中,將擷取的token 首先放入 cookie 中,這樣,下次 axios 請求時可以從 cookie 中取值並佈建要求頭,其他使用者資訊等在依此根據 token 去擷取並存入 localStorage 中。

  不過問題就出現在 _blank 上(這是技術選型的時候沒有考慮的,vue 比較適合 spa 項目),如果我先以一個帳號資訊進入子系統的一個模組(開啟了一個新標籤頁),然後不關閉這個頁面回到父系統的視窗,切換帳號登陸父系統,任然點擊進入同一個子系統的模組,此時會發現,這次進入時拉取的資料是依據 localStorage 中存放的前一個 userId 拉取的,但是,F5 重新整理一下就能拉取正確資訊,這就不合理了。

  後來閱讀源碼,發現,子系統中最基礎的子組件中某些關鍵資訊都是從 localStorage 中擷取,而每個模組中都有 postMessage 方法,只不過這個方法是在父組件的 mounted 階段才調用,這就是導致了上面的換帳號後進入模組,子組件根據 localStorage/cookie 中的前帳號資訊先去拉取資料,完成初始化,到所有子組件的初始化完成後父組件才執行 mounted 中 postMessage 方法,擷取並在 cookie 中設定後帳號的 token  ,然後 F5 重新整理時,所用的要求標頭中是後帳號的 token,才拉取到正確的資料。

  這裡面的父子組件的生命週期是:

  1.載入渲染過程:

父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted

   2.子組件更新過程

父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated

   3.父組件更新過程

父 beforeUpdate -> 父 updated

   4.銷毀過程

父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed

 

  明白了父子組件的渲染時間點,那在父組件 beforeCreate / created / beforeMount 時調用 postMessage 方法不就可以了嗎?

  答案是不行。為什嗎?因為非同步。我嘗試了,在 父組件 的上面三個階段內調用 postMessage 方法,其回呼函數的執行一定會落後於子組件的渲染掛載,即 子組件憑藉 cookie / loaclStorage 裡面的前帳號資訊拉取資料 一定會在 後帳號的 token 被存放到 cookie 中之前執行,這是其一;其二,因為 vue 推薦的是 axios 請求模組,這是一個非同步請求模組,即使在父組件三個階段內去更新使用者資訊,這一步依然會落後於子組件的渲染掛載。

 

  那麼如何解決?

  我的解決辦法:組件內路由鉤子 beforeRouteEnter(to, from, next)

  在這個鉤子中,調用 postMessage,擷取 最新 token, 在其回呼函數中,憑藉新的 token, 使用 jquery(本來項目中有依賴)發送 一個拉取使用者關鍵資訊的 ajax 請求,這個請求設定成同步,擷取到資料後,將相關資訊更新到 cookie / localStorage 中,確保後續的請求都是依據最新的使用者資訊。在確保上面的操作全部完成之後,next() 到想要的路由上去。

 

  尾聲:

  axios 中沒有同步請求,$.ajax 也不推薦使用同步請求。需求如此,尚未找到更好的解決辦法,vue 仍需探索。

 

vue 關於生命週期

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.