vue2.x生命周期鉤子函數
組件的生命周期分為3個階段:
- 掛載階段:
beforeCreate
、created
、beforeMount
、mounted
, - 更新階段:
beforeUpdate
、updated
, - 銷毀階段:
beforeDestroy
、destroyed
beforeCreate
beforeCreate() {// 初始化數據,并通過Object.defineProperty()和給組件實例配置watcher觀察者實例(發布-訂閱者模式),實現數據監測// 該步驟可以用來檢測vue是否開始實例化// data中的數據與el還未初始化,無法通過Vue實例來訪問data中的數據、computed、watch、methods等中的方法。
}
created
created() {// 實例已完成以下配置:數據觀測、屬性和方法的運算,watch/event事件回調,完成了data 數據的初始化,可以訪問data、computed、watch、methods上的方法和數據。但是,未掛載到DOM,不能訪問到el屬性,el屬性,ref屬性內容為空。
}
beforeMount
beforeMount() {//頁面呈現的是未經Vue編譯的DOM結構,所有對DOM的操作,最終都不奏效。
}
mounted
mounted() {//頁面呈現的是經過vue編譯的dom,對dom的操作均有效,至此,初始化階段全部完成,一般在此執行:開啟定時器,發送網絡請求,訂閱消息,綁定自定義事件等初始化操作。
}
beforeUpdate
beforeUpdate() {//當數據發生變化,執行beforeUpdate鉤子函數,此時,內存中數據是新的,但是頁面是舊的,也就是在這個鉤子函數中,頁面和數據不同步
}// beforeUpdate執行結束之后,重新生成一個新的虛擬dom(vnode),用它和原來的Vnode做比較(diff算法)patch指的就是這個比較的過程,更新render函數中的數據,之后之后將render函數渲染成真實dom,完成了 Model --> View 的更新
updated
updated() {// 頁面和數據保持同步
}
beforeDestory
beforeDestroy() {// 在銷毀前,在實例中所有的data,methods,computed,指令等,都處于可用狀態;一般進行:關閉定時器,取消訂閱消息解綁自定義事件等收尾工作。
}
destory
destoryed() {// 當前實例,視圖層和邏輯層的關系解綁// 例如計時器,dom事件監聽器或者與服務器的連接
}
父子組件鉤子函數在三個階段的代碼執行順序
掛載: 父親created > 子created > 子mounted > 父親mounted >
更新: 父親beforeUpdate > 子beforeUpdated > 子updated > 父親updated
銷毀: 父親beforeDestroy > 子beforeDestroy > 子destroyed > 父destroyed
========================================================
keep-alive組件的鉤子函數
deactivated
deactivated() {// 非激活
}
activated
activated() {// 激活
}
// 保活的頁面希望頁面顯示時立刻刷新頁面的數據 比如購物車
// 保持活動,不會銷毀,而是激活與非激活,點回去就是激活,點走就是非激活
使用場景:
// 1. 用戶在某個列表頁面選擇篩選條件過濾出一份數據列表,由列表頁面進入數據詳情頁面,再返回該列表頁面,我們希望:列表頁面可以保留用戶的篩選(或選中)狀態
// 2. keep-alive就是用來解決這種場景。當然keep-alive不僅僅是能夠保存頁面/組件的狀態這么簡單,它還可以避免組件反復創建和渲染,有效提升系統性能。總的來說,keep-alive用于保存組件的渲染狀態
// 3. 使用keep-alive緩存組件本身是為了提高頁面的性能,快速加載頁面,但有時候在特定場景和條件中,比如在其他的組件對數據庫中的數據發生更改,我們需要去更新當前組件的數據狀態,而因為組件沒有銷毀,所以created和mounted鉤子函數都不執行,deactivated和activated就是用來解決這個問題。
如何使用(觸發)
當組件被keep - alive包裹時, 再次進入此組件, 此時組件是處于存活的情況下;
如果當前組件存在activated() 函數, 一進入組件activated() 立即觸發;
這時我們就可以根據特定的條件去初始化組件數據。 當離開存在deactivated() 函數的組件時, 因為此時組件對象已經處于存活狀態下, 所以一離開組件deactivated() 函數就觸發(也可以根據特定的條件做一些事情)
========================================================
路由中的鉤子函數(6個)
全局路由鉤子函數:beforeEach afterEach
全局前置鉤子beforeEach
// 在每一個路由改變的時候都要執行一遍
router.beforeEach((to, from, next) => {// to 目標路由對象// from 當前導航正要離開的路由對象// next(Function函數),一定要調用該方法來resolve這個鉤子。調用方法:next(參數或者空) ***必須調用// next(無參數的時候): 進行管道中的下一個鉤子,如果走到最后一個鉤子函數,那么 導航的狀態就是 confirmed (確認的)
})
// 應用場景:
// 1. 進行一些頁面跳轉前的處理,例如跳轉到的頁面需要進行登錄才可以訪問時,就會做登錄的跳轉
// 2. 進入頁面登錄判斷,管理員權限判斷,瀏覽器判斷
全局后置鉤子afterEach
// afterEach 被調用時,路由已經跳轉完成,所以不需要 next 函數router.afterEach((to,from)=>{})
單個的路由鉤子函數:beforeEnter
// 路由獨享的守衛beforeEnter
// 可以直接在路由配置上直接定義beforeEnter,這些守衛與全局前置守衛的方法參數是一樣的
beforeEnter((to, from, next) => {.....
})
組件內的路由鉤子函數:beforeRouteEnter beforeRouteLeave beforeRouteUpdate
- 使用場景:
- 消除組件中的定時器
- 當頁面有未關閉的窗口,或未保存的內容時,阻止頁面跳轉
- 保存相關內到Vuex和Session中
beforeRouteEnter
beforeRouteEnter(to, from, next) {// 在渲染該組件的對應路由被confirm前調用// 不能獲取組件實例 this// 因為當鉤子執行時,組件實例還沒有被創建
}
beforeRouteUpdate
beforeRouteUpdate(to, from, next) {// 在當前路由改變,但是組件被復用時調用// 舉例來說,對于一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候。// 由于會渲染同樣的Foo組件,因此組件實例會被復用。而這個鉤子就會在這個情況下被調用。// 可以訪問組件實例 this}
beforeRouteLeave
beforeRouteLeave(to, from, next) {// 導航離開該組件的對應路由時調用// 可以訪問組件實例 this
}
========================================================
組件自定義指令中的鉤子函數direction(v2.x)
-
對普通dom元素進行底層操作
Vue.directive('指令名稱', {})
-
bind
: 指令被綁到元素上的時候使用, 只會執行一次Vue.directive('color', {bind: function(el) { //el就是被綁定的元素el.style.color = "red"}})
-
inserted
: 綁定指令的元素被添加到父元素上的時候使用, 只會執行一次Vue.directive('focus', {inserted: function(el) {el.focus()}})
-
update
: 所在組建的VNode更新時調用, 但是可能發生在其子VNode更新之前, 也就是說元素更新, 但子元素尚未更新, 將調用此鉤子(自定義指令所在組件更新時執行, 但是不保證更新完成)— > 和自定義所在組件有關Vue.directive('color', {update: function(el) {el.style.color = "blue"}})
-
componentUpdated
: 組件和子級更新后執行(自定義指令所在組件更新完成, 且子組件也完成更新).Vue.directive('color', {componentUpdated: function(el) {el.style.color = "yellow"}})
-
unbind
: 解綁(銷毀) 自定義指令所在的dom銷毀時執行, 只調用一次.
========================================================
組件自定義指令中的鉤子函數direction(v3.x)
created
- 自定義指令所在組件, 創建后beforeMount
- 就是Vue2.x中的 bind, 自定義指令綁定到 DOM 后調用.只調用一次, 注意: 只是加入進了DOM, 但是渲染沒有完成mounted
- 就是Vue2.x中的 inserted, 自定義指令所在DOM, 插入到父 DOM 后調用, 渲染已完成(最最重要)beforeUpdate
- 自定義指令所在 DOM, 更新之前調用updated
- 就是Vue2.x中的 componentUpdatedbeforeUnmount
- 銷毀前unmounted
- 銷毀后
========================================================
vue3.x生命周期鉤子函數 (函數式開發)
import {defineComponent,ref,toRefs,watch,computed,onUpdated....} from 'vue'
//setup函數替代了vuejs.2.x的beforeCreate和created鉤子函數
1. onBeforeMount
onBeforeMount(()=>{// 在組件被掛載之前被調用,當這個鉤子被調用時,組件已經完成其響應式狀態的設置,但還沒有創建DOM節點,即將首次執行DOM渲染過程。})
onMounted
onMounted(()=>{// 在組件被掛載之前被調用,當這個鉤子被調用時,組件已經完成其響應式狀態的設置,但還沒有創建DOM節點,即將首次執行DOM渲染過程。})
onBeforeUpdate
onBeforeUpdate(()=>{//在組件即將因為響應式狀態變更而更新其DOM樹之前調用,在beforeUpdate鉤子函數執行時,組件的DOM還未更新,如果你想在組件更新前訪問DOM,比如手動移除已添加的事件監聽器,你可以注冊這個鉤子函數
})
onUpdated
onUpdated(()=>{//在組件因為響應式狀態變更而更新其DOM樹之后調用,父組件的更新鉤子將在其子組件的更新鉤子之后使用。 某些邏輯,最好不要使用updated鉤子函數而用計算屬性或watcher取而代之,因為任何數據的變化導致的組件更新都會執行updated鉤子函數。注意:不要在updated鉤子函數中更新數據,因為這樣會再次觸發組件更新,導致無限遞歸更新。父組件的更新不一定會導致子組件的更新,因為更新粒度是組件級別的。
})
onBeforeUnmount
onBeforeUnmount(()=>{// 在組件實例被卸載之前調用,當這個鉤子被調用時,組件實列依然還保留全部的功能
})
onUnmount
onUnmounted(()=>{// 在組件實列被卸載之后調用,其所有子組件都已經被卸載。可以在這個鉤子中手動清理一些副作用,例如計時器,dom事件監聽器或者與服務器的連接
})
onErrorCapture
onErrorCaptured(()=>{// 注冊一個鉤子,在捕獲了后代組件傳遞的錯誤時調用。
})