一:Vue的生命周期方法有哪些?一般在哪一步發起請求及原因?
核心答案:
總共分為8個階段:創建前/后,載入前/后,更新前/后,銷毀前/后。
1、創建前/后:
1) beforeCreate階段:vue實例的掛載元素el和數據對象data都為undefined,還未初始化。
說明:在當前階段data、methods、computed以及watch上的數據和方法都不能被訪問。
2) created階段:vue實例的數據對象data有了,el還沒有。
說明:可以做一些初始數據的獲取,在當前階段無法與Dom進行交互,如果非要想,可以通過vm.$nextTick來訪問Dom。
2、載入前/后:
1) beforeMount階段:vue實例的$el和data都初始化了,但還是掛載之前為虛擬的dom節點。
說明:當前階段虛擬Dom已經創建完成,即將開始渲染。在此時也可以對數據進行更改,不會觸發updated。
2) mounted階段:vue實例掛載完成,data.message成功渲染。
說明:在當前階段,真實的Dom掛載完畢,數據完成雙向綁定,可以訪問到Dom節點,使用$refs屬性對Dom進行操作。
3、更新前/后:
1) beforeUpdate階段:響應式數據更新時調用,發生在虛擬DOM打補丁之前,適合在更新之前訪問現有的DOM,比如手動移除已添加的事件監聽器。
說明:可以在當前階段進行更改數據,不會造成重渲染。
2) updated階段:虛擬DOM重新渲染和打補丁之后調用,組成新的DOM已經更新,避免在這個鈎子函數中操作數據,防止死循環。
說明:當前階段組件Dom已完成更新。要注意的是避免在此期間更改數據,因為這可能會導致無限循環的更新。
4、銷毀前/后:
1) beforeDestroy階段:實例銷毀前調用,實例還可以用,this能獲取到實例,常用於銷毀定時器,解綁事件。
說明:在當前階段實例完全可以被使用,我們可以在這時進行善后收尾工作,比如清除計時器。
2) destroyed階段:實例銷毀后調用,調用后所有事件監聽器會被移除,所有的子實例都會被銷毀。
說明:當前階段組件已被拆解,數據綁定被卸除,監聽被移出,子實例也統統被銷毀。
補充回答:
第一次頁面加載時會觸發:beforeCreate, created, beforeMount, mounted。
1) created 實例已經創建完成,因為它是最早觸發的原因可以進行一些數據,資源的請求。(服務器渲染支持created方法)
2) mounted 實例已經掛載完成,可以進行一些DOM操作。(接口請求)
源碼地址:src/core/instance/lifecycle.js
二:生命周期鈎子是如何實現的?
核心答案:
Vue的生命周期鈎子就是回調函數而已,當創建組件實例的過程中會調用對應的鈎子方法。
補充回答:
內部主要是使用callHook方法來調用對應的方法。核心是一個發布訂閱模式,將鈎子訂閱好(內部采用數組的方式存儲),在對應的階段進行發布。
源碼地址:src/core/util/options.js 146 core/instance/lifecycle.js 336
三:Vue 的父組件和子組件生命周期鈎子執行順序?
核心答案:
第一次頁面加載時會觸發 beforeCreate, created, beforeMount, mounted 這幾個鈎子。
渲染過程:
父組件掛載完成一定是等子組件都掛載完成后,才算是父組件掛載完,所以父組件的mounted在子組件mouted之后
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted
子組件更新過程:
影響到父組件:父beforeUpdate -> 子beforeUpdate->子updated -> 父updted
不影響父組件:子beforeUpdate -> 子updated
父組件更新過程:
影響到子組件:父beforeUpdate -> 子beforeUpdate->子updated -> 父updted
不影響子組件:父beforeUpdate -> 父updated
銷毀過程:
父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed
重要:父組件等待子組件完成后,才會執行自己對應完成的鈎子。
來自VUE中文社區公眾號 https://mp.weixin.qq.com/s/60HI-CM1GhqDG5zeTFSOrw