序言:
1. vue 單元件的生命週期;
2. vue 父子元件的生命週期;
3. axios 非同步請求 與 vue 的元件週期;
vue的生命週期 - **淺白
簡單總結:
1.beforecreate 此時 $el、data 的值都為 undefined ;
2.created 此時可以拿到 data 中的值,但是 this.$el 任然是 undefined ;
3.beforemounte 此時可以列印 this.$el, 但是當中的 } 還沒有被替換,this.$el 是虛擬節點;
4.mounted data,$el 均可以被列印,} 也已經被替換成正式的 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 -> 父 mounted2.子元件更新過程
父 beforeupdate -> 子 beforeupdate -> 子 updated -> 父 updated3.父元件更新過程
父 beforeupdate -> 父 updated4.銷毀過程
父 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() 到想要的路由上去。
當然,es 7 的 async/await api 可以替換調使用 jquery 的部分,從而解決問題。2020/04/20
尾聲:axios 中沒有同步請求,$.ajax 也不推薦使用同步請求。需求如此,尚未找到更好的解決辦法,vue 仍需探索。
關於vue的生命週期
關於vue的生命週期我們來看下這個官方的圖 從圖中我們很容易看的出vue元件的生命週期的鉤子函式有以下這些 下面分別說以下這些生命週期 beforecreate 這個生命週期如上圖所示 例項初始化在這個生命週期遍歷 data 物件下所有屬性將其轉化為 getter setter,也就是說新增乙個被觀...
vue生命週期
beforecreate 元件例項剛剛被建立,屬性都沒有 create 例項已經建立完成,屬性已經繫結 beforemount 模板編譯之前 mounted 模板編譯之後 beforeupdate 元件更新之前 updated 元件更新完畢 beforedestroy 元件銷毀之前 destroye...
vue生命週期
vue把整個生命週期劃分為建立 掛載 更新 銷毀等階段,每個階段都會給一些 鉤子 讓我們來做一些我們想實現的動作。學習例項的生命週期,能幫助我們理解vue例項的運作機制,更好地合理利用各個鉤子來完成我們的業務 我們分別來看看這幾個階段 1.beforecreate 此階段為例項初始化之後,此時的資料...