前端JS概念之鉤子、生命周期及掛載詳解
怎么理解編程中的鉤子
鉤子(Hook)是編程中一種巧妙的技術(shù),它允許在程序執(zhí)行的特定節(jié)點(diǎn)"插入"自定義代碼,從而在不修改核心源碼的情況下改變或擴(kuò)展程序的行為。
下面這個(gè)表格匯總了核心要點(diǎn),快速建立整體認(rèn)識(shí):
| 方面 | 核心理解 | 常見(jiàn)示例或?qū)崿F(xiàn)方式 |
|---|---|---|
| ???? 本質(zhì)?? | 一種事件驅(qū)動(dòng)的回調(diào)機(jī)制,用于攔截或處理系統(tǒng)、應(yīng)用或框架中的特定事件或消息。 | onClick, useEffect, @app.before_request |
| ???? 主要目的?? | ??擴(kuò)展功能??、??行為定制??、??實(shí)現(xiàn)解耦??。?? | 插件系統(tǒng)、日志記錄、權(quán)限檢查、性能監(jiān)控 |
| ???? 工作原理?? | ?? 在預(yù)定義的"鉤子點(diǎn)"(Hook Point)注冊(cè)回調(diào)函數(shù),當(dāng)特定事件發(fā)生時(shí),這些函數(shù)會(huì)被自動(dòng)調(diào)用。 ?? | 框架提供注冊(cè)接口(如 register_forward_hook),開(kāi)發(fā)者編寫處理函數(shù) |
| ???? 觸發(fā)時(shí)機(jī)???? | 事件發(fā)生前、后,或替代原有處理。 ?? | 請(qǐng)求前/后(before_request, after_request)、組件掛載/更新前/后(onMounted)、方法執(zhí)行前/后(裝飾器) |
| ???? 常見(jiàn)類型???? | 函數(shù)/方法鉤子、事件鉤子、消息鉤子、系統(tǒng)鉤子。?? | Python裝飾器、Django信號(hào)、Windows消息鉤子、瀏覽器事件監(jiān)聽(tīng) |
| ???? 優(yōu)勢(shì)?? | ?? ??解耦??、??靈活擴(kuò)展??、??非侵入式??。 ?? | 核心邏輯與擴(kuò)展邏輯分離,易于維護(hù)和添加新功能。 |
| ???? 注意事項(xiàng)???? | ??性能??(過(guò)多鉤子可能影響效率)、??復(fù)雜度??(邏輯分散可能增加理解難度)、??安全??(不當(dāng)使用可能引入漏洞)。?? | 避免循環(huán)調(diào)用,確保必要時(shí)的鉤子卸載(如系統(tǒng)級(jí)鉤子)。 |
鉤子的常見(jiàn)應(yīng)用場(chǎng)景
鉤子的應(yīng)用非常廣泛,幾乎遍布軟件開(kāi)發(fā)各個(gè)領(lǐng)域:
• ??Web開(kāi)發(fā)??:框架(如 Flask、Django)常用鉤子處理??請(qǐng)求生命周期??(請(qǐng)求前/后、用戶認(rèn)證等)。
• ??前端框架??:React 的 useEffect、Vue 的 onMounted 等??生命周期鉤子??用于處理組件不同階段邏輯。
• ??操作系統(tǒng)/系統(tǒng)編程??:攔截??系統(tǒng)消息??(如鍵盤鼠標(biāo)輸入)、??API調(diào)用??監(jiān)控或修改。
• ??深度學(xué)習(xí)??:PyTorch 等框架允許在模型前向/反向傳播時(shí)注冊(cè)鉤子,??提取中間特征??或??梯度??。
• ??插件系統(tǒng)??:許多軟件(如 WordPress)通過(guò)鉤子機(jī)制允許第三方開(kāi)發(fā)者??擴(kuò)展功能??。
鉤子的一些實(shí)現(xiàn)方式
在不同編程語(yǔ)言和環(huán)境中,鉤子的實(shí)現(xiàn)形式多樣:
• ??裝飾器(Python)??:通過(guò)在函數(shù)/方法定義前添加 @decorator_name,??包裝??其行為,是一種常見(jiàn)的函數(shù)鉤子。
• ??回調(diào)函數(shù)/事件監(jiān)聽(tīng)??:??注冊(cè)??一個(gè)函數(shù),在特定事件發(fā)生時(shí)被調(diào)用,JavaScript 中的事件處理是典型例子。
• ??框架提供的特定機(jī)制??:許多框架(如 Django 的??信號(hào)機(jī)制??、Flask 的??請(qǐng)求鉤子??)內(nèi)置了鉤子系統(tǒng)。
如何理解鉤子
- ??想象成“事件監(jiān)聽(tīng)器”??:鉤子像是預(yù)先安放在程序關(guān)鍵點(diǎn)的“監(jiān)聽(tīng)器”或“哨兵”,一旦關(guān)注的事件發(fā)生,它就“報(bào)告”并執(zhí)行你設(shè)定的任務(wù)。
- ??理解為“可定制的插入點(diǎn)”??:框架或程序預(yù)留了許多“插口”(鉤子點(diǎn)),你只需把“插頭”(自定義函數(shù))插上去,功能便得以擴(kuò)展。
- ??核心是“回調(diào)”??:鉤子的本質(zhì)是??回調(diào)函數(shù)??(Callback Function)的應(yīng)用。你將一個(gè)函數(shù)“注冊(cè)”給系統(tǒng),系統(tǒng)在適當(dāng)時(shí)候“回調(diào)”它。
使用鉤子的注意事項(xiàng)
雖然鉤子強(qiáng)大,也需謹(jǐn)慎使用:
• ??性能影響??:鉤子函數(shù)執(zhí)行會(huì)??增加開(kāi)銷??,尤其注冊(cè)過(guò)多或包含復(fù)雜邏輯時(shí)可能影響性能。
• ??邏輯復(fù)雜度??:過(guò)度使用鉤子可能使??代碼邏輯分散??,增加理解和調(diào)試難度。
• ??安全風(fēng)險(xiǎn)??:??惡意代碼??可能通過(guò)鉤子注入執(zhí)行,系統(tǒng)級(jí)鉤子使用尤需謹(jǐn)慎。
• ??兼容性與維護(hù)??:鉤子行為可能??依賴特定框架或系統(tǒng)版本??,需注意兼容性,并確保正確注冊(cè)和注銷。
總結(jié)
簡(jiǎn)單來(lái)說(shuō),鉤子就是一種??“事件發(fā)生時(shí),自動(dòng)執(zhí)行你預(yù)設(shè)函數(shù)”的機(jī)制??。它通過(guò)??解耦??和??事件驅(qū)動(dòng)??,讓程序更??靈活、易擴(kuò)展??。
怎么理解生命周期鉤子
“生命周期鉤子”,把它拆成“生命周期”和“鉤子”兩部分來(lái)看。
它本質(zhì)上是??框架或系統(tǒng)在特定對(duì)象(如Vue組件、應(yīng)用程序)創(chuàng)建、更新、銷毀等一系列關(guān)鍵時(shí)間點(diǎn),為我們預(yù)留的、可以插入自定義代碼的“接口”或“機(jī)會(huì)”??。
下面表格匯總了Vue.js中生命周期鉤子的核心階段和主要鉤子函數(shù):
| 階段 | 鉤子函數(shù) | 觸發(fā)時(shí)機(jī) | 主要用途 |
|---|---|---|---|
| ??創(chuàng)建階段?? | beforeCreate?? | 實(shí)例初始化后,數(shù)據(jù)觀測(cè)和事件配置前?? | 執(zhí)行一些不依賴于組件數(shù)據(jù)的初始化邏輯 |
| ?? | created ?? | 實(shí)例創(chuàng)建完成,數(shù)據(jù)觀測(cè)已完成?? | ??發(fā)送異步請(qǐng)求??、初始化數(shù)據(jù)、調(diào)用方法 |
| ??掛載階段?? | ?? beforeMount?? | 模板編譯完成,但尚未掛載到DOM ?? | 掛載前的準(zhǔn)備工作 |
| ?? | mounted?? | 實(shí)例被掛載到DOM后 ???? | 操作DOM??、??初始化第三方庫(kù)??(如圖表、地圖) |
| ??更新階段?? | ?? beforeUpdate?? | 數(shù)據(jù)變化后,虛擬DOM重新渲染和打補(bǔ)丁前 | 獲取更新前的DOM狀態(tài) |
| ?? | updated?? | 數(shù)據(jù)變化導(dǎo)致虛擬DOM重新渲染和打補(bǔ)丁后 ?? | 操作更新后的DOM?? |
| ??銷毀階段?? | ?? beforeDestroy (Vue 2) / beforeUnmount (Vue 3)?? | 實(shí)例銷毀前 | ??清理工作??(如清除定時(shí)器、取消事件監(jiān)聽(tīng)、取消未完成的網(wǎng)絡(luò)請(qǐng)求) |
| ?? | destroyed (Vue 2) / unmounted (Vue 3)?? | 實(shí)例銷毀后 | 執(zhí)行一些最終的清理工作,如通知外部系統(tǒng)組件已銷毀 |
理解“生命周期”??
“生命周期”指的是一個(gè)事物從??創(chuàng)建??、??運(yùn)行??到??銷毀??的整個(gè)過(guò)程。
在前端框架(如Vue、React)或一些系統(tǒng)中,這通常指的是一個(gè)組件或應(yīng)用實(shí)例所經(jīng)歷的從初始化、掛載、更新到卸載的一系列階段。
??理解“鉤子”??
“鉤子”是一種編程機(jī)制,允許在特定事件或時(shí)間點(diǎn)“掛載”或“注入”自己的代碼。
可以把它想象成是框架在運(yùn)行到某個(gè)特定時(shí)刻時(shí),主動(dòng)向你發(fā)出的一個(gè)“邀請(qǐng)”或“通知”,告訴你“我現(xiàn)在準(zhǔn)備做某事了,你要不要趁這個(gè)機(jī)會(huì)做點(diǎn)什么?”。
??生命周期鉤子的核心價(jià)值??
生命周期鉤子的主要目的是讓開(kāi)發(fā)者有機(jī)會(huì)在??對(duì)象生命周期的關(guān)鍵節(jié)點(diǎn)??執(zhí)行自己的代碼,從而更好地控制對(duì)象的行為和管理資源。這使得開(kāi)發(fā)者能夠:
• ??在合適的時(shí)機(jī)做合適的事??:例如,在組件創(chuàng)建后(created)請(qǐng)求數(shù)據(jù),在組件掛載后(mounted)操作DOM,在組件銷毀前(beforeDestroy/beforeUnmount)清理資源以防止內(nèi)存泄漏。
•?? 實(shí)現(xiàn)更靈活和精細(xì)的控制??:通過(guò)在不同的生命周期階段插入邏輯,可以更有效地管理組件的狀態(tài)和行為。
??一個(gè)簡(jiǎn)單的比喻??
可以把組件的生命周期想象成人的一生:
• created -> 出生了,有了基本的身份信息(數(shù)據(jù)),但還無(wú)法與世界互動(dòng)(DOM)。
• mounted -> 長(zhǎng)大成人,正式步入社會(huì),可以工作和創(chuàng)造價(jià)值(操作DOM)。
• updated -> 經(jīng)歷了一些事情,成長(zhǎng)改變了。
• beforeDestroy/beforeUnmount -> 預(yù)感生命將至盡頭,開(kāi)始處理身后事,歸還物品,告別朋友(清除定時(shí)器、解綁事件)。
• destroyed/unmounted -> 生命結(jié)束。
使用注意事項(xiàng)??
• ??避免在 beforeUpdate 或 updated 中更改狀態(tài)??,這可能引發(fā)無(wú)限循環(huán)更新。
• ??異步操作需謹(jǐn)慎??:在 mounted 等鉤子中進(jìn)行異步操作時(shí),要考慮到組件可能在你得到異步響應(yīng)之前就已經(jīng)被銷毀了。
• ??理解父子組件生命周期順序??:對(duì)于父子組件,生命周期鉤子的執(zhí)行是有順序的,例如在掛載階段,順序是:父 beforeMount -> 子 beforeMount -> 子 mounted -> 父 mounted。
??其他系統(tǒng)中的生命周期鉤子??
生命周期鉤子的概念并不僅限于Vue.js。在許多其他框架和系統(tǒng)中也存在類似的機(jī)制:
• ??React??:有 componentDidMount, componentDidUpdate, componentWillUnmount 等生命周期方法(在類組件中),以及 useEffect Hook(在函數(shù)組件中)來(lái)實(shí)現(xiàn)類似功能。
• ??鴻蒙系統(tǒng)??:同樣提供了豐富的生命周期鉤子,例如對(duì)于UIAbility有 onCreate, onWindowStageCreate, onDestroy 等;對(duì)于頁(yè)面組件有 aboutToAppear, aboutToDisappear 等,用于管理應(yīng)用和組件的創(chuàng)建、顯示、隱藏與銷毀過(guò)程。
掛載的理解
理解“掛載”(Mounting),關(guān)鍵要明白它在??不同領(lǐng)域有不同含義??,但核心思想都是??將某個(gè)對(duì)象“關(guān)聯(lián)”或“安裝”到另一個(gè)對(duì)象上,使其成為可用整體??。
下面主要從計(jì)算機(jī)領(lǐng)域,尤其是文件系統(tǒng)和前端開(kāi)發(fā)的角度梳理:
| 領(lǐng)域 掛載對(duì)象 | 掛載目標(biāo) | 核心目的 |
|---|---|---|
| ??操作系統(tǒng)/文件系統(tǒng)?? | 磁盤分區(qū)、外部存儲(chǔ)設(shè)備 | 目錄樹(shù)中的空目錄(掛載點(diǎn)) |
| ??Vue.js?? | Vue實(shí)例或組件 | DOM元素 |
| ??React?? | React組件 DOM樹(shù) | 渲染用戶界面并管理組件狀態(tài) |
| ??其他領(lǐng)域?? | 車牌、裝飾物、知識(shí)產(chǎn)權(quán)、證據(jù) | 車輛、建筑物、他人、法律案件 |
看看這幾個(gè)主要領(lǐng)域的掛載:
操作系統(tǒng)與文件系統(tǒng)掛載
在操作系統(tǒng)(如 Linux)中,“掛載”指??將存儲(chǔ)設(shè)備(如硬盤分區(qū)、U盤、光盤)的文件系統(tǒng)連接到目錄樹(shù)中的某個(gè)空目錄(稱為“掛載點(diǎn)”),從而能夠訪問(wèn)設(shè)備中的數(shù)據(jù)??。
• ??為何需要掛載??:Linux/Unix 系統(tǒng)中,“一切皆文件”,硬件設(shè)備也被視為文件。但設(shè)備文件(如 /dev/sda1)本身不包含數(shù)據(jù),而是設(shè)備的入口。通過(guò)掛載,用戶才能通過(guò)熟悉的目錄路徑訪問(wèn)設(shè)備中的文件和數(shù)據(jù)。
• ??掛載點(diǎn)??:通常是??空目錄??。選擇空目錄是為了避免掛載后原有目錄內(nèi)容被隱藏。
•?? 掛載命令??:在 Linux 中常用 mount 命令。
• ??卸載??:不再需要訪問(wèn)設(shè)備時(shí),使用 umount 命令解除關(guān)聯(lián)關(guān)系。
簡(jiǎn)單比喻??
就像給家里增加一個(gè)儲(chǔ)物柜(存儲(chǔ)設(shè)備)。柜子本身不能直接放東西,你需要給它指定一個(gè)位置(掛載點(diǎn),比如客廳角落),并把它固定在那里(掛載)。之后,你就可以通過(guò)“客廳角落的儲(chǔ)物柜”來(lái)存取物品了。
前端框架中的掛載
在前端框架(如 Vue.js、React)中,“掛載”指??將組件實(shí)例關(guān)聯(lián)到真實(shí)的 DOM 元素上, 從而將組件渲染到頁(yè)面中并建立交互聯(lián)系??。
Vue.js 中的掛載
在 Vue.js 中,掛載是將 Vue 實(shí)例關(guān)聯(lián)到 DOM 元素的過(guò)程。
- 掛載方式??:
• ??自動(dòng)掛載??:創(chuàng)建 Vue 實(shí)例時(shí)通過(guò) el 選項(xiàng)指定掛載點(diǎn)。
new Vue({
el: '#app', // 掛載到 id 為 app 的元素上
data: { message: 'Hello Vue!' }
})
• ??手動(dòng)掛載??:創(chuàng)建實(shí)例時(shí)不指定 el,之后通過(guò) $mount 方法掛載。
const vm = new Vue({ data: { message: 'Hello Vue!' } })
vm.$mount('#app') // 手動(dòng)掛載
- ??掛載過(guò)程的生命周期鉤子??:
• beforeMount:模板已編譯,但尚未將虛擬 DOM 渲染為真實(shí) DOM。
• mounted:實(shí)例已掛載到 DOM,可進(jìn)行 DOM 操作或發(fā)送異步請(qǐng)求。
• ??重要性??:掛載后,Vue 的??響應(yīng)式系統(tǒng)??開(kāi)始工作,數(shù)據(jù)變化可驅(qū)動(dòng)視圖更新。
React 中的掛載
React 中,掛載是組件首次被渲染到 DOM 中的過(guò)程。
掛載過(guò)程的生命周期方法??(類組件):
• constructor:初始化 state 和綁定事件。
• static getDerivedStateFromProps:在渲染前根據(jù) props 派生 state。
• render:返回需要渲染的 JSX 內(nèi)容。
• componentDidMount:組件已掛載到 DOM,是進(jìn)行??副作用操作??(如數(shù)據(jù)請(qǐng)求、訂閱事件)的理想時(shí)機(jī)。
簡(jiǎn)單比喻??
就像把一個(gè)電器(組件實(shí)例)插到電源(DOM 元素)上并打開(kāi)開(kāi)關(guān)(掛載),電器才開(kāi)始工作(渲染和交互)。
其他領(lǐng)域的掛載
“掛載”一詞在其他領(lǐng)域也表示“附加”或“關(guān)聯(lián)”的概念:
• ??車輛交通??:將車牌、標(biāo)志牌固定到車輛特定位置。
• ??房地產(chǎn)建筑??:將裝飾物、燈具等固定到建筑物表面。
• ??知識(shí)產(chǎn)權(quán)??:將專利、商標(biāo)等授權(quán)給他人使用。
• ??法律證據(jù)??:將文件或證據(jù)與特定案件關(guān)聯(lián)。
核心思想
無(wú)論哪個(gè)領(lǐng)域,“掛載”的核心思想都是:??建立一種連接或附屬關(guān)系,使得被掛載的對(duì)象能夠通過(guò)掛載目標(biāo)被訪問(wèn)、使用或生效??。
總結(jié)
到此這篇關(guān)于前端JS概念之鉤子、生命周期及掛載的文章就介紹到這了,更多相關(guān)JS鉤子、生命周期及掛載內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
又一款js時(shí)鐘!transform實(shí)現(xiàn)時(shí)鐘效果
又一款js時(shí)鐘!這篇文章主要為大家詳細(xì)介紹了transform實(shí)現(xiàn)的時(shí)鐘效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08
JS高仿拋物線加入購(gòu)物車特效實(shí)現(xiàn)代碼
本篇文章主要介紹了JS高仿拋物線加入購(gòu)物車特效實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-02-02
給localStorage設(shè)置一個(gè)過(guò)期時(shí)間的方法分享
我們都知道localStorage不主動(dòng)刪除,永遠(yuǎn)不會(huì)銷毀,那么如何設(shè)置localStorage的過(guò)期時(shí)間呢?下面這篇文章主要給大家介紹了關(guān)于如何給localStorage設(shè)置一個(gè)過(guò)期時(shí)間的相關(guān)資料,需要的朋友可以參考下2018-11-11
js統(tǒng)計(jì)錄入文本框中字符的個(gè)數(shù)并加以限制不超過(guò)多少
為了更直觀的體現(xiàn)用戶在文本框輸入文本時(shí)能看到自己輸入了多少字,并且有些特殊的要求字?jǐn)?shù)不超過(guò)多少,本文給出了具體的實(shí)現(xiàn)2014-05-05
JavaScript計(jì)算字符串實(shí)際長(zhǎng)度方法示例
這篇文章主要為大家介紹了JavaScript計(jì)算字符串實(shí)際長(zhǎng)度方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08

