Vue框架之鉤子函數詳解

Vue框架之生命周期主要鉤子函數詳解

    • 一、Vue生命周期的整體流程
    • 二、創建階段:初始化組件實例
      • 2.1 `beforeCreate`:實例創建前
      • 2.2 `created`:實例創建后
    • 三、掛載階段:組件與DOM結合
      • 3.1 `beforeMount`:掛載前
      • 3.2 `mounted`:掛載后
    • 四、更新階段:數據變化觸發重渲染
      • 4.1 `beforeUpdate`:更新前
      • 4.2 `updated`:更新后
    • 五、銷毀階段:組件實例的清理
      • 5.1 `beforeDestroy`:銷毀前
      • 5.2 `destroyed`:銷毀后
    • 六、特殊場景的鉤子函數
      • 6.1 keep-alive 相關鉤子
      • 6.2 錯誤捕獲鉤子:`errorCaptured`
    • 七、生命周期鉤子的執行順序與實戰示例
      • 7.1 單組件執行順序
      • 7.2 父子組件執行順序
    • 八、常見問題與避坑指南
      • 8.1 避免在`updated`中修改數據
      • 8.2 子組件`mounted`晚于父組件`mounted`
      • 8.3 清理資源是重中之重
    • 九、Vue 3中的生命周期變化

Vue的生命周期是指組件從創建到銷毀的整個過程,而生命周期鉤子函數則是在這個過程中特定時間點自動執行的函數。掌握這些鉤子函數,能讓我們在合適的時機執行特定操作(如數據請求、DOM操作、資源清理等),是Vue開發的核心基礎。

一、Vue生命周期的整體流程

Vue組件的生命周期可分為4個階段,每個階段包含若干鉤子函數,整體流程如下:

  1. 創建階段:組件實例從初始化到掛載前的過程
  2. 掛載階段:組件實例掛載到DOM的過程
  3. 更新階段:組件數據變化導致重新渲染的過程
  4. 銷毀階段:組件實例從DOM中移除并清理資源的過程

二、創建階段:初始化組件實例

創建階段是組件實例從無到有的過程,主要完成數據觀測(響應式處理)、事件初始化等工作,此時尚未涉及DOM操作。

2.1 beforeCreate:實例創建前

  • 執行時機:Vue實例初始化后(new Vue()之后),數據觀測(dataprops)和事件機制初始化前調用。
  • 特點
    • 無法訪問datapropsmethods中的數據和方法(此時尚未初始化)。
    • 不能進行DOM操作(DOM尚未生成)。
  • 適用場景:極少使用,可用于初始化非響應式數據(如臨時變量)。
new Vue({data() {return { message: 'Hello' };},beforeCreate() {console.log('beforeCreate:', this.message); // undefined(無法訪問data)console.log('methods:', this.getMsg); // undefined(無法訪問methods)},methods: {getMsg() { return this.message; }}
});

2.2 created:實例創建后

  • 執行時機:Vue實例初始化完成后調用,此時已完成dataprops的響應式處理和methods的綁定,但尚未開始DOM編譯(模板未掛載到DOM)。
  • 特點
    • 可訪問datapropsmethods中的數據和方法。
    • 仍無法進行DOM操作($el屬性不存在,DOM未生成)。
  • 適用場景
    • 發起初始化數據請求(如獲取列表數據)。
    • 初始化數據(如對data中的數據進行預處理)。
    • 綁定自定義事件。
new Vue({el: '#app',data() {return { list: [] };},created() {console.log('created:', this.list); // [](可訪問data)console.log('$el:', this.$el); // undefined(DOM未掛載)// 示例:發起數據請求axios.get('/api/list').then(response => {this.list = response.data; // 數據響應后更新list(響應式)});}
});

三、掛載階段:組件與DOM結合

掛載階段是組件實例與DOM關聯的過程,核心是將編譯后的模板掛載到頁面中,此時開始具備DOM操作能力。

3.1 beforeMount:掛載前

  • 執行時機:模板編譯(解析指令、插值表達式等)完成后,DOM掛載到頁面之前調用。
  • 特點
    • 已完成模板編譯,生成虛擬DOM(但未渲染到頁面)。
    • $el屬性存在(指向即將掛載的DOM元素),但內容仍為原始模板(未替換數據)。
    • 仍無法操作DOM(數據未渲染,操作無意義)。
  • 適用場景:極少使用,可用于獲取模板編譯前的DOM結構。
new Vue({el: '#app',template: '<div>{{ message }}</div>',data() { return { message: '掛載前' }; },beforeMount() {console.log('beforeMount $el:', this.$el); // <div>{{ message }}</div>(未替換)console.log('頁面內容:', document.getElementById('app').innerHTML); // 原始模板}
});

3.2 mounted:掛載后

  • 執行時機:模板掛載到DOM后調用,此時頁面已顯示渲染后的內容。
  • 特點
    • DOM已完全渲染,可通過$el或原生DOM API(如document.getElementById)操作DOM。
    • 子組件的mounted可能在父組件的mounted之后執行(因渲染順序)。
  • 適用場景
    • 執行DOM操作(如初始化第三方UI插件:圖表、地圖等,需依賴DOM元素)。
    • 監聽DOM事件(如滾動、resize)。
    • 若數據請求依賴DOM尺寸(如根據容器寬度請求不同數據),可在此發起請求。
new Vue({el: '#app',data() { return { width: 0 }; },mounted() {// 獲取DOM元素寬度this.width = this.$el.offsetWidth;console.log('掛載后寬度:', this.width);// 初始化第三方圖表插件(假設頁面有<div id="chart"></div>)this.chart = new Chart(document.getElementById('chart'), {type: 'line',data: { labels: ['1月', '2月'], datasets: [{ data: [10, 20] }] }});// 監聽滾動事件window.addEventListener('scroll', this.handleScroll);},methods: {handleScroll() { /* 處理滾動邏輯 */ }}
});

四、更新階段:數據變化觸發重渲染

當組件的dataprops發生變化時,會進入更新階段,觸發重新渲染,此階段的鉤子函數用于監控或干預更新過程。

4.1 beforeUpdate:更新前

  • 執行時機:數據發生變化后,虛擬DOM重新渲染前調用。
  • 特點
    • 此時data中的數據已更新,但DOM尚未重新渲染(頁面顯示舊數據)。
    • 可獲取更新前的DOM狀態。
  • 適用場景:獲取更新前的DOM信息(如滾動位置、輸入框光標位置),用于更新后恢復狀態。
new Vue({el: '#app',data() { return { count: 0 }; },template: '<div>{{ count }} <button @click="count++">+1</button></div>',beforeUpdate() {console.log('更新前data:', this.count); // 新值(如1)console.log('更新前DOM:', this.$el.textContent); // 舊值(如0)}
});

4.2 updated:更新后

  • 執行時機:虛擬DOM重新渲染并更新到頁面后調用,此時頁面顯示最新數據。
  • 特點
    • data和DOM均已更新,可獲取最新的DOM狀態。
    • 若在updated中修改data,會再次觸發更新(可能導致無限循環,需避免)。
  • 適用場景
    • 基于最新DOM狀態執行操作(如根據新內容調整元素樣式)。
    • 同步第三方插件數據(如圖表數據更新后,重新繪制圖表)。
new Vue({el: '#app',data() { return { data: [10, 20] }; },template: '<div>{{ data }}</div>',updated() {console.log('更新后DOM:', this.$el.textContent); // 顯示最新data// 若圖表數據依賴this.data,更新后重新繪制if (this.chart) {this.chart.data.datasets[0].data = this.data;this.chart.update();}}
});

五、銷毀階段:組件實例的清理

當組件被銷毀(如v-if="false"移除組件、路由切換)時,進入銷毀階段,此階段的鉤子函數用于清理資源,避免內存泄漏。

5.1 beforeDestroy:銷毀前

  • 執行時機:組件實例銷毀前調用,此時組件仍處于正常工作狀態。
  • 特點
    • 可訪問datamethods、DOM等所有資源。
    • 子組件的beforeDestroy會在父組件的beforeDestroy前執行。
  • 適用場景
    • 清理定時器、事件監聽器(避免組件銷毀后仍執行)。
    • 取消未完成的請求(避免資源浪費)。
    • 解綁自定義事件。
new Vue({el: '#app',data() {return { timer: null };},mounted() {// 啟動定時器this.timer = setInterval(() => {console.log('定時器執行中...');}, 1000);// 綁定事件window.addEventListener('resize', this.handleResize);},beforeDestroy() {// 清理定時器clearInterval(this.timer);// 移除事件監聽window.removeEventListener('resize', this.handleResize);// 取消未完成的請求(假設使用axios)if (this.source) {this.source.cancel('組件銷毀,取消請求');}},methods: {handleResize() { /* 處理窗口大小變化 */ }}
});

5.2 destroyed:銷毀后

  • 執行時機:組件實例銷毀后調用,此時組件的所有資源已被釋放。
  • 特點
    • 組件的響應式數據、事件監聽、子組件等均已被銷毀。
    • 仍可訪問$el,但DOM可能已被移除(取決于銷毀方式)。
  • 適用場景:極少使用,可用于最終的資源清理或日志記錄。
new Vue({destroyed() {console.log('組件已銷毀');// 記錄銷毀日志console.log('組件銷毀時間:', new Date().toLocaleString());}
});

六、特殊場景的鉤子函數

除上述核心鉤子外,Vue還提供了針對特殊場景的鉤子函數:

6.1 keep-alive 相關鉤子

keep-alive用于緩存組件(避免頻繁創建/銷毀),搭配兩個專屬鉤子:

  • activated:緩存的組件被激活(顯示)時調用。
  • deactivated:緩存的組件被停用(隱藏)時調用。
<!-- 緩存組件 -->
<keep-alive><component :is="currentComponent"></component>
</keep-alive><script>
new Vue({data() { return { currentComponent: 'ComponentA' }; },components: {ComponentA: {template: '<div>組件A</div>',activated() {console.log('組件A被激活(從緩存中取出)');// 可在此恢復狀態(如刷新數據)},deactivated() {console.log('組件A被停用(存入緩存)');// 可在此暫停操作(如暫停視頻播放)}}}
});
</script>

6.2 錯誤捕獲鉤子:errorCaptured

用于捕獲子組件拋出的錯誤(Vue 2.5+),返回false可阻止錯誤向上傳播:

new Vue({errorCaptured(err, vm, info) {console.error('捕獲子組件錯誤:', err, '組件:', vm, '信息:', info);// 返回false阻止錯誤冒泡到控制臺return false;}
});

七、生命周期鉤子的執行順序與實戰示例

7.1 單組件執行順序

new Vue({// 創建階段beforeCreate() { console.log('1. beforeCreate'); },created() { console.log('2. created'); },// 掛載階段beforeMount() { console.log('3. beforeMount'); },mounted() { console.log('4. mounted'); },// 更新階段(觸發條件:修改data)beforeUpdate() { console.log('5. beforeUpdate'); },updated() { console.log('6. updated'); },// 銷毀階段(觸發條件:調用$destroy()或v-if移除)beforeDestroy() { console.log('7. beforeDestroy'); },destroyed() { console.log('8. destroyed'); }
});

執行結果
初始化時:1→2→3→4
修改數據時:5→6
銷毀時:7→8

7.2 父子組件執行順序

父組件Parent和子組件Child的鉤子執行順序:

  1. beforeCreate → 父created → 父beforeMount
  2. beforeCreate → 子created → 子beforeMount → 子mounted
  3. mounted
  4. (更新時)父beforeUpdate → 子beforeUpdate → 子updated → 父updated
  5. (銷毀時)父beforeDestroy → 子beforeDestroy → 子destroyed → 父destroyed

結論:父組件等待子組件完成后,才會完成自身對應的階段。

八、常見問題與避坑指南

8.1 避免在updated中修改數據

// 錯誤示例:導致無限循環
updated() {this.count++; // 修改data觸發更新,再次調用updated,循環往復
}

解決方案:若需根據更新后的數據調整狀態,可使用$nextTick或條件判斷限制執行次數。

8.2 子組件mounted晚于父組件mounted

父組件若需等待子組件掛載完成后執行操作(如獲取子組件DOM),需使用$nextTick或在子組件中通過事件通知父組件:

// 子組件
export default {mounted() {this.$emit('mounted'); // 通知父組件已掛載}
};// 父組件
<child-component @mounted="handleChildMounted"></child-component>
methods: {handleChildMounted() {console.log('子組件已掛載');}
}

8.3 清理資源是重中之重

組件銷毀時若未清理定時器、事件監聽等,會導致內存泄漏(頁面關閉前資源一直占用):

// 錯誤:未清理定時器
mounted() {setInterval(() => { /* 操作 */ }, 1000); // 組件銷毀后仍會執行
}// 正確:在beforeDestroy中清理
beforeDestroy() {clearInterval(this.timer);
}

九、Vue 3中的生命周期變化

Vue 3的Composition API中,生命周期鉤子的使用方式有所調整,但核心邏輯一致:

  • setup():替代beforeCreatecreated(在兩者之間執行)。
  • onBeforeMount:對應beforeMount
  • onMounted:對應mounted
  • onBeforeUpdate:對應beforeUpdate
  • onUpdated:對應updated
  • onBeforeUnmount:對應beforeDestroy
  • onUnmounted:對應destroyed
// Vue 3 Composition API示例
import { onMounted, onBeforeUnmount } from 'vue';export default {setup() {let timer;onMounted(() => {timer = setInterval(() => { /* 操作 */ }, 1000);});onBeforeUnmount(() => {clearInterval(timer); // 清理資源});}
};

總結

  1. 精準控制流程:在合適的階段執行合適的操作(如created請求數據、mounted操作DOM)。
  2. 避免常見問題:如更新階段的死循環、銷毀階段的內存泄漏。
  3. 優化組件性能:合理利用keep-alive和緩存鉤子,減少不必要的創建/銷毀。

若這篇內容幫到你,動動手指支持下!關注不迷路,干貨持續輸出!
ヾ(′? ˋ)ノヾ(′? ˋ)ノヾ(′? ˋ)ノヾ(′? ˋ)ノヾ(′? ˋ)ノ

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/88776.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/88776.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/88776.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Syntax Error: TypeError: Cannot set properties of undefined (setting ‘parent‘)

Date: 2025-07-12 19:21:24 author: lijianzhan使用npm run dev運行前端項目時報錯&#xff0c;具體報錯信息如下&#xff1a; ERROR Failed to compile with 1 error …

JAVA后端開發——類命名規范

引言良好的命名規范是軟件工程的基石。它不僅能提升代碼的可讀性&#xff0c;還能降低團隊協作的溝通成本&#xff0c;使項目在長期迭代中更易于維護。本規范結合了業界主流實踐&#xff08;如阿里巴巴Java開發手冊&#xff09;以及現代Web應用分層架構的特點&#xff0c;旨在提…

Ubuntu2404修改國內鏡像

文章目錄1 備份原文件2 修改文件內容Ubuntu2404修改國內鏡像 2404和2204修改鏡像的方式不一致 且鏡像保存的位置也不一致&#xff0c;位置在/etc/apt/source.list.d/ubuntu.sources 參考&#xff1a;https://blog.csdn.net/Kiffy_Yam/article/details/145876447 1 備份原文件…

Chrome拓展 Video Speed Controller 等內嵌惡意后門

【高危】Chrome拓展 Video Speed Controller 等內嵌惡意后門 漏洞描述 當用戶安裝受影響版本的 Video Speed Controller 等Chrome拓展會竊取用戶的瀏覽鏈接&#xff0c;并與攻擊者可控的C2地址建立持久化連接&#xff0c;攻擊者可將用戶瀏覽器重定向到惡意網站。 MPS編號MPS…

Spring Ai Alibaba Gateway 實現存量應用轉 MCP 工具

作者簡介&#xff1a;你好&#xff0c;我是影子&#xff0c;Spring Ai Alibaba開源社區 Committer&#xff0c;持續分享Spring Ai Alibaba最新進展 業界各類AI工程相關的方案 最近有斷時間沒更了&#xff0c;熟悉我的朋友知道我剛結束完畢業旅行&#xff0c;最近也因為入職&a…

HTTP和HTTPS部分知識點

HTTP基本概念 超文本-傳輸-協議 協議 HTTP是一個用在計算機世界里的協議。它使用計算機可以理解的語言確立了一種計算機之間交流通信的規范(兩個以上的參與者)&#xff0c;以及相關的各種控制和錯誤處理方式(行為約定和規范)。傳輸 HTTP協議是一個雙向協議。是一個在計算機世界…

第10講——一元函數積分學的幾何應用

文章目錄定積分計算平面圖形的面積直角坐標系下參數方程下極坐標系下定積分計算旋轉體的體積曲邊梯形繞x軸旋轉一周所得到的旋轉體的體積曲邊梯形繞y軸旋轉一周所得到的旋轉體的體積平面曲線繞定直線旋轉定積分計算函數的平均值定積分計算平面光滑曲線的弧長曲線L繞x軸旋轉一周…

Go從入門到精通(20)-一個簡單web項目-服務搭建

Go從入門到精通&#xff08;15&#xff09;-包&#xff08;package&#xff09; Go從入門到精通&#xff08;9&#xff09;-函數 文章目錄Go從入門到精通&#xff08;15&#xff09;-包&#xff08;package&#xff09;Go從入門到精通&#xff08;9&#xff09;-函數前言gogin…

Python爬蟲實戰:研究python-docx庫相關技術

1. 引言 1.1 研究背景與意義 隨著學術資源數字化程度的提高,科研工作者面臨海量文獻數據的篩選與分析挑戰。傳統人工調研方式效率低下,難以全面捕捉研究領域的動態趨勢。自動化文獻分析系統能夠通過爬蟲技術快速采集多源數據,并通過文本挖掘提取關鍵信息,為研究方向選擇、…

Django中序列化與反序列化

1&#xff1a;序列化&#xff1a;將數據結構或對象狀態轉換為可以存儲或傳輸的格式&#xff08;如JSON、XML&#xff09;的過程。在Web開發中&#xff0c;通常是將模型實例&#xff08;或查詢集&#xff09;轉換為JSON格式&#xff0c;以便通過HTTP響應發送給客戶端。序列化&am…

【離線數倉項目】——電商域DWD層開發實戰

摘要本文主要介紹了離線數倉項目中電商域DWD層的開發實戰。DWD層是數據倉庫架構中的明細數據層&#xff0c;對ODS層的原始數據進行清洗、規范、整合與業務建模。它具有數據清洗、標準化、業務建模、整合、維度掛載等作用&#xff0c;常見設計特征包括一致性、明細級建模、保留歷…

爬蟲-正則使用

1.模塊選擇用re模塊導入&#xff0c;&#xff0c;最前面加個r&#xff0c;就不用怕轉義了2.模塊使用re.findall使用結果是數組方式呈現re.finditer把結果變成迭代器&#xff0c;從迭代器類中間取數re.searchre.search 只能匹配到第一個識別到的內容re.match3.推薦寫法先預加載完…

python-range函數

文章目錄基本用法重要特性與列表轉換注意事項遍歷回去列表的元素索引range()是Python中用于生成數字序列的內置函數&#xff0c;常用于循環和序列生成。基本用法 range(stop) # 生成0到stop-1的整數序列 range(start, stop) # 生成start到stop-1的整數序列 r…

汽車功能安全-軟件集成和驗證(Software Integration Verification)【目的、驗證輸入、集成驗證要求】9

文章目錄1 目的2 驗證輸入3 軟件集成要求3.1 要求和建議3.2 汽車行業示例&#xff08;混合動力控制器軟件&#xff09;4 驗證要求1 目的 軟件集成和驗證階段的核心目標是證明集成后的軟件單元&#xff08;模塊、組件&#xff09;已經正確地開發出來&#xff0c;滿足了所有的功…

每天一個前端小知識 Day 27 - WebGL / WebGPU 數據可視化引擎設計與實踐

WebGL / WebGPU 數據可視化引擎設計與實踐&#x1f3af; 一、為什么前端需要 WebGL / WebGPU&#xff1f; 傳統的圖表庫如 ECharts、Highcharts 基于 Canvas 或 SVG&#xff0c;適合 2D 渲染&#xff0c;但&#xff1a; 當數據量 > 1 萬時&#xff0c;SVG 性能瓶頸明顯&…

JavaScript代碼段注入:動態抓取DOM元素的原理與實踐

1.F12打開網頁說明&#xff1a;以百度網站為例。通過插入代碼塊抓取當前網頁dom元素。2.新代碼段說明&#xff1a;點擊源代碼/來源菜單項下面的代碼段。點擊新代碼段新增代碼段。下面以腳本代碼段#6為例。3.編寫代碼塊說明&#xff1a;編寫javascript代碼&#xff0c;點擊下面的…

Spring Easy

Spring Easy 用途 通過自動配置&#xff0c;實現了一些國內 Spring Boot 開發時需要在 Spring Boot 框架基礎上完成的一些配置工作&#xff0c;可以提升基于 Spring Boot 開發 Web 應用的效率。 安裝 使用 Maven 進行包管理&#xff0c;可以從中央倉庫安裝依賴&#xff1a;…

【Node.js】文本與 pdf 的相互轉換

pdf 轉文本 主要使用 pdf-parse 這個庫&#xff0c;直接識別提取我們 pdf 文件中的文字。 const express require("express"); const fs require("fs"); const PDFParser require("pdf-parse"); const cors require("cors");const…

分布式ID方案

目錄 &#x1f4ca; 分布式ID方案核心指標對比 &#x1f50d; 分方案深度解析 ?? 1. UUID (Universally Unique Identifier) ?? 2. Snowflake (Twitter開源) ?? 3. 美團Leaf 號段模式 Snowflake模式 &#x1f504; 4. 百度UidGenerator &#x1f680; 5. CosId …

張量類型轉換

一.前言本章節我們來講解張量的類型轉換&#xff0c;掌握張量的轉換方法&#xff0c;張量的類型轉換也是經常使?的?種操作&#xff0c;是必須掌握的知識點。在本?節&#xff0c;我們主要學習如何將 numpy 數組和 PyTorch Tensor 的轉化?法.二.張量轉換為 numpy 數組使? Te…