Vue 生命周期全解析:從創建到銷毀的完整旅程

Vue 生命周期是每個 Vue 開發者必須深入理解的核心概念之一。它定義了組件從創建、掛載、更新、銷毀的整個過程,以及在這個過程中各個階段提供的鉤子函數。掌握生命周期不僅能幫助你理解 Vue 的工作原理,還能讓你在合適的時機執行特定的操作,優化應用性能,避免常見陷阱。本文將從源碼實現到實際應用,全面解析 Vue 生命周期的各個階段。

一、生命周期概覽

Vue 組件的生命周期可以分為四個主要階段:

  1. 初始化與掛載:創建組件實例,初始化數據,掛載 DOM
  2. 數據更新:響應式數據變更時觸發更新流程
  3. 銷毀:清理組件并釋放資源
  4. 特殊場景:錯誤處理、服務器端渲染等

每個階段都提供了相應的鉤子函數,開發者可以在這些鉤子中注入自定義邏輯。生命周期鉤子的執行順序是固定的,理解這個順序對于編寫正確的代碼至關重要。

二、生命周期階段詳解

2.1 初始化與掛載階段

這個階段從組件實例創建開始,到 DOM 掛載完成結束。

2.1.1 beforeCreate
  • 觸發時機:實例初始化之后,數據觀測 (data observer) 和 event/watcher 事件配置之前被調用。
  • 特性
    • 此時 this 指向實例,但數據和方法均未初始化。
    • 無法訪問 datamethodscomputed
    • 通常用于初始化非響應式數據或全局插件。
  • 示例
    export default {beforeCreate() {// 初始化全局事件總線this.$bus = new Vue();// 記錄組件創建時間this._createdAt = Date.now();}
    }
    
2.1.2 created
  • 觸發時機:實例已經創建完成之后被調用。在這一步,實例已經完成了數據觀測、propertymethod 的計算、watch/event 事件回調的配置。然而,掛載階段還沒有開始,$el 屬性目前不可用。
  • 特性
    • 可以訪問 datamethodscomputed,但 DOM 尚未掛載。
    • 適合進行數據獲取(如 API 請求)或初始化依賴數據的操作。
  • 示例
    export default {data() {return {users: []};},async created() {try {const response = await fetch('/api/users');this.users = await response.json();} catch (error) {console.error('Failed to fetch users', error);}}
    }
    
2.1.3 beforeMount
  • 觸發時機:掛載開始之前被調用。
  • 特性
    • 模板編譯/渲染函數已經完成,但尚未掛載到 DOM。
    • $el 是虛擬 DOM,不可訪問實際 DOM 元素。
    • 適合在渲染前對模板進行最后的修改。
  • 源碼關鍵點
    // Vue 源碼簡化版
    vm.$el = vm.$options.el;
    callHook(vm, 'beforeMount');// 編譯模板生成 render 函數
    const updateComponent = () => {vm._update(vm._render(), hydrating);
    };
    
2.1.4 mounted
  • 觸發時機:掛載完成后被調用。此時模板已經編譯完成并掛載到 DOM 上。
  • 特性
    • 可以訪問 $el 和實際 DOM 元素。
    • 子組件已經完成掛載(但不保證所有異步子組件都已完成)。
    • 適合進行 DOM 操作、初始化第三方插件(如 Chart.js、Leaflet)或訂閱事件。
  • 示例
    export default {mounted() {// 初始化圖表this.chart = new Chart(this.$el.querySelector('#chart'), {type: 'bar',data: this.chartData});// 添加 DOM 事件監聽器this.$el.addEventListener('click', this.handleClick);},beforeDestroy() {// 清理圖表實例和事件監聽器this.chart.destroy();this.$el.removeEventListener('click', this.handleClick);}
    }
    
2.2 數據更新階段

這個階段在組件數據發生變化時觸發,包含虛擬 DOM 重新渲染和打補丁的過程。

2.2.1 beforeUpdate
  • 觸發時機:數據更新時調用,發生在虛擬 DOM 打補丁之前。
  • 特性
    • 數據已經變更,但 DOM 尚未更新。
    • 可以訪問更新前的 DOM 狀態。
    • 適合在更新前保存當前 DOM 狀態或執行一些預處理。
  • 示例
    export default {data() {return {list: [1, 2, 3]};},beforeUpdate() {// 保存更新前的列表高度this.prevListHeight = this.$el.offsetHeight;}
    }
    
2.2.2 updated
  • 觸發時機:由于數據更改導致的虛擬 DOM 重新渲染和打補丁之后調用。
  • 特性
    • 數據和 DOM 都已經更新。
    • 可以訪問更新后的 DOM 狀態。
    • 注意:不要在這個鉤子中修改數據,否則可能導致無限循環更新。
  • 示例
    export default {updated() {// 對比更新前后的列表高度,執行動畫if (this.prevListHeight !== this.$el.offsetHeight) {this.animateListHeightChange();}}
    }
    
2.3 銷毀階段

這個階段在組件實例銷毀時觸發,用于清理資源和事件監聽器。

2.3.1 beforeDestroy (Vue 2) / beforeUnmount (Vue 3)
  • 觸發時機:實例銷毀之前調用。此時實例仍然完全可用。
  • 特性
    • 組件仍然完全正常工作。
    • 適合進行資源清理(如定時器、事件監聽器、WebSocket 連接等)。
  • 示例
    export default {created() {this.timer = setInterval(() => {console.log('定時任務');}, 1000);this.$bus.$on('some-event', this.handleEvent);},beforeDestroy() {// 清理定時器clearInterval(this.timer);// 取消事件訂閱this.$bus.$off('some-event', this.handleEvent);}
    }
    
2.3.2 destroyed (Vue 2) / unmounted (Vue 3)
  • 觸發時機:實例已經完全銷毀之后調用。
  • 特性
    • 所有的事件監聽器和子實例已經被銷毀。
    • 組件實例完全不可用。
    • 通常用于確認資源是否已經正確釋放。
  • 源碼關鍵點
    // Vue 源碼簡化版
    callHook(vm, 'beforeDestroy');// 遞歸銷毀子組件
    vm.$children.forEach(child => {child.$destroy();
    });// 移除所有事件監聽器
    vm._events = Object.create(null);callHook(vm, 'destroyed');
    
2.4 特殊場景鉤子
2.4.1 activated / deactivated
  • 觸發時機
    • activated:被 <keep-alive> 緩存的組件激活時調用。
    • deactivated:被 <keep-alive> 緩存的組件停用時調用。
  • 特性
    • 只在使用 <keep-alive> 包裹的組件中觸發。
    • 適合處理緩存組件的特殊邏輯(如恢復滾動位置、刷新數據)。
  • 示例
    <keep-alive><router-view />
    </keep-alive>
    
    export default {activated() {// 組件被激活時刷新數據this.fetchData();},deactivated() {// 保存組件狀態this.saveScrollPosition();}
    }
    
2.4.2 errorCaptured (Vue 2) / errorCaptured + renderTracked + renderTriggered (Vue 3)
  • 觸發時機
    • errorCaptured:捕獲來自子孫組件的錯誤時調用。
    • renderTracked / renderTriggered(Vue 3):用于調試響應式依賴的追蹤和觸發。
  • 特性
    • 可以阻止錯誤繼續向上傳播。
    • 適合實現全局錯誤處理或日志記錄。
  • 示例
    export default {errorCaptured(err, vm, info) {// 記錄錯誤日志console.error('Error captured:', err, info);// 可以返回 false 阻止錯誤繼續向上傳播return false;}
    }
    
2.4.3 serverPrefetch (Vue 3 僅 SSR)
  • 觸發時機:在服務器端渲染(SSR)期間,組件實例在服務器上被創建時調用。
  • 特性
    • 僅在 SSR 模式下有效。
    • 用于在服務器端預取數據,避免客戶端重復請求。
  • 示例
    export default {async serverPrefetch() {// 在服務器端預取數據this.data = await fetchData();}
    }
    

三、生命周期流程圖與執行順序

3.1 Vue 2 生命周期流程圖
創建實例↓
beforeCreate↓
初始化 data/methods↓
created↓
是否有 el 選項?↓├─ 否 → 等待 vm.$mount(el)↓├─ 是 → 是否有 template 選項?↓├─ 是 → 編譯 template 為 render 函數↓└─ 否 → 使用 el 的 outerHTML 作為 template↓
beforeMount↓
創建 vm.$el 并替換 el↓
mounted↓
數據變更↓
beforeUpdate↓
虛擬 DOM 重新渲染 & 打補丁↓
updated↓
調用 vm.$destroy()↓
beforeDestroy↓
銷毀所有子實例、事件監聽器和子組件↓
destroyed
3.2 Vue 3 生命周期變更

Vue 3 對生命周期鉤子進行了一些重命名,以更準確地反映其用途:

  • beforeDestroybeforeUnmount
  • destroyedunmounted

新增鉤子:

  • setup():替代 beforeCreatecreated,是 Composition API 的入口點。
  • renderTracked / renderTriggered:用于調試響應式依賴。

四、生命周期鉤子的實際應用場景

4.1 數據獲取
  • 最佳位置createdmounted
  • 選擇依據
    • 如果數據獲取不依賴 DOM 操作,使用 created(稍早執行)。
    • 如果需要訪問 DOM 元素,使用 mounted
  • 示例
    export default {data() {return {posts: [],loading: true,error: null};},async created() {try {const response = await fetch('/api/posts');this.posts = await response.json();} catch (error) {this.error = error.message;} finally {this.loading = false;}}
    }
    
4.2 DOM 操作與第三方插件集成
  • 最佳位置mounted
  • 示例:初始化 Chart.js 圖表
    export default {mounted() {const ctx = this.$el.querySelector('#myChart').getContext('2d');this.chart = new Chart(ctx, {type: 'line',data: this.chartData,options: this.chartOptions});},beforeUnmount() {// 銷毀圖表實例this.chart.destroy();}
    }
    
4.3 狀態恢復與保存
  • 最佳位置activated / deactivated(配合 <keep-alive>
  • 示例:保存和恢復滾動位置
    export default {data() {return {scrollPosition: 0};},deactivated() {// 保存當前滾動位置this.scrollPosition = window.scrollY;},activated() {// 恢復滾動位置window.scrollTo(0, this.scrollPosition);}
    }
    
4.4 資源清理
  • 最佳位置beforeDestroy / beforeUnmount
  • 示例:清理定時器、取消訂閱、關閉網絡連接
    export default {created() {this.socket = new WebSocket('ws://example.com');this.interval = setInterval(this.updateData, 5000);},beforeUnmount() {// 清理 WebSocket 連接this.socket.close();// 清除定時器clearInterval(this.interval);}
    }
    
4.5 全局狀態初始化
  • 最佳位置beforeCreate
  • 示例:初始化全局事件總線或配置
    export default {beforeCreate() {// 初始化全局事件總線this.$bus = new Vue();// 配置全局 API 基地址this.$apiBaseUrl = process.env.VUE_APP_API_BASE_URL;}
    }
    

五、生命周期鉤子的性能考慮

5.1 避免在鉤子中執行耗時操作
  • 問題:在 mountedupdated 等鉤子中執行大量計算或同步 API 請求會阻塞 UI 渲染。
  • 解決方案
    • 使用異步操作(如 async/await)處理 API 請求。
    • 將復雜計算移至 computed 屬性或 watch 中。
    export default {async mounted() {// 錯誤:同步執行大量計算// this.result = heavyCalculation(this.data);// 正確:異步執行setTimeout(() => {this.result = heavyCalculation(this.data);}, 0);// 或使用 Web Workerthis.worker.postMessage(this.data);this.worker.onmessage = (e) => {this.result = e.data;};}
    }
    
5.2 避免在 updated 中修改數據
  • 問題:在 updated 中修改數據會觸發新的更新周期,可能導致無限循環。
  • 解決方案
    • 僅在數據滿足特定條件時才修改,且確保不會再次觸發更新。
    export default {updated() {// 錯誤:可能導致無限循環// if (this.value < 10) this.value++;// 正確:使用 nextTick 避免立即觸發更新if (this.value < 10 && !this.updating) {this.updating = true;this.$nextTick(() => {this.value++;this.updating = false;});}}
    }
    
5.3 合理使用生命周期鉤子
  • 問題:在不需要的鉤子中添加邏輯會增加組件復雜度和執行時間。
  • 解決方案
    • 只在真正需要的鉤子中添加代碼。
    • 使用 Composition API 將相關邏輯組織在一起,減少對生命周期鉤子的依賴。

六、Vue 3 Composition API 中的生命周期

Vue 3 的 Composition API 提供了與生命周期鉤子等效的函數,使邏輯復用更加靈活:

6.1 等效鉤子映射
選項式 APIComposition API
beforeCreatesetup()
createdsetup()
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroyonBeforeUnmount
destroyedonUnmounted
errorCapturedonErrorCaptured
renderTrackedonRenderTracked (僅開發模式)
renderTriggeredonRenderTriggered (僅開發模式)
6.2 示例:使用 Composition API 訪問生命周期
import { onMounted, onBeforeUnmount, ref } from 'vue';export default {setup() {const count = ref(0);let timer;// 等效于 mountedonMounted(() => {timer = setInterval(() => {count.value++;}, 1000);});// 等效于 beforeUnmountonBeforeUnmount(() => {clearInterval(timer);});return {count};}
};
6.3 Composition API 的優勢
  • 邏輯復用:可以將相關生命周期邏輯封裝到可復用的函數中。
  • 代碼組織:將同一功能的代碼集中在一起,提高可讀性。
  • 類型安全:更好地支持 TypeScript,提供更準確的類型推導。

七、生命周期鉤子的常見誤區與解決方案

7.1 誤區:在 mounted 中直接操作子組件 DOM
  • 問題:子組件可能尚未完全掛載,直接訪問子組件 ref 會失敗。
  • 解決方案
    • 使用 nextTick 確保子組件已掛載。
    • 使用事件或 props 進行組件間通信。
    export default {mounted() {// 錯誤:子組件可能尚未掛載// this.$refs.child.doSomething();// 正確:使用 nextTickthis.$nextTick(() => {this.$refs.child.doSomething();});}
    }
    
7.2 誤區:在 destroyed 中訪問組件實例
  • 問題:在 destroyed 鉤子中,組件實例已經完全銷毀,訪問 this 可能導致錯誤。
  • 解決方案
    • beforeDestroy 中進行所有清理操作。
    export default {beforeDestroy() {// 正確:此時組件仍然可用this.cleanupResources();},destroyed() {// 錯誤:不要在這里訪問 this// this.cleanupResources(); // 可能導致錯誤}
    }
    
7.3 誤區:過度使用生命周期鉤子
  • 問題:在多個生命周期鉤子中重復相同的邏輯,導致代碼冗余。
  • 解決方案
    • 使用 Composition API 將相關邏輯封裝到一個函數中。
    • 使用 watchcomputed 處理數據變化邏輯。
    // 壞:重復邏輯
    export default {mounted() {this.initData();},activated() {this.initData();},methods: {initData() {// 初始化邏輯}}
    };// 好:使用 Composition API 封裝
    import { onMounted, onActivated } from 'vue';export function useInitData(initFn) {onMounted(initFn);onActivated(initFn);
    }// 在組件中使用
    export default {setup() {useInitData(() => {// 初始化邏輯});}
    };
    

八、生命周期源碼解析(簡化版)

Vue 的生命周期實現主要涉及以下幾個核心模塊:

  1. 實例初始化src/core/instance/init.js
  2. 生命周期鉤子src/core/instance/lifecycle.js
  3. 渲染流程src/core/instance/render.js
  4. 更新流程src/core/observer/watcher.js
8.1 關鍵源碼片段
// src/core/instance/init.js
Vue.prototype._init = function(options) {const vm = this;// 初始化生命周期狀態initLifecycle(vm);// 初始化事件系統initEvents(vm);// 初始化渲染initRender(vm);// 調用 beforeCreate 鉤子callHook(vm, 'beforeCreate');// 初始化注入initInjections(vm);// 初始化 data、props、computed 等initState(vm);// 初始化 provideinitProvide(vm);// 調用 created 鉤子callHook(vm, 'created');if (vm.$options.el) {// 掛載組件vm.$mount(vm.$options.el);}
};// src/core/instance/lifecycle.js
Vue.prototype.$mount = function(el) {// 編譯模板并生成 render 函數const mount = Vue.prototype._mount;const vm = this;// 調用 beforeMount 鉤子callHook(vm, 'beforeMount');// 執行渲染const vnode = vm._render();vm._update(vnode, hydrating);// 調用 mounted 鉤子callHook(vm, 'mounted');return vm;
};// 數據更新觸發的更新流程
Watcher.prototype.update = function() {const vm = this.vm;// 調用 beforeUpdate 鉤子callHook(vm, 'beforeUpdate');// 執行虛擬 DOM 更新vm._update(vm._render(), hydrating);// 調用 updated 鉤子callHook(vm, 'updated');
};// 組件銷毀流程
Vue.prototype.$destroy = function() {const vm = this;// 調用 beforeDestroy 鉤子callHook(vm, 'beforeDestroy');// 執行銷毀操作:移除事件監聽器、銷毀子組件等vm._isBeingDestroyed = true;// 遞歸銷毀子組件vm.$children.forEach(child => {child.$destroy();});// 移除所有事件監聽器vm._events = Object.create(null);// 調用 destroyed 鉤子callHook(vm, 'destroyed');vm._isDestroyed = true;
};

九、總結與最佳實踐

9.1 生命周期關鍵要點總結
  1. 初始化與掛載

    • beforeCreate:實例初始化后,數據和事件系統尚未初始化。
    • created:數據觀測、propertymethod 計算完成,可進行數據獲取。
    • beforeMount:模板編譯完成,但尚未掛載到 DOM。
    • mounted:DOM 掛載完成,可進行 DOM 操作和第三方插件初始化。
  2. 數據更新

    • beforeUpdate:數據變更后,DOM 更新前。
    • updated:DOM 更新完成,避免在此修改數據。
  3. 銷毀階段

    • beforeDestroy/beforeUnmount:實例銷毀前,可進行資源清理。
    • destroyed/unmounted:實例完全銷毀,不可訪問組件狀態。
  4. 特殊場景

    • activated/deactivated<keep-alive> 緩存組件的激活/停用。
    • errorCaptured:捕獲子孫組件的錯誤。
9.2 最佳實踐建議
  1. 數據獲取:優先在 created 中進行,避免阻塞 DOM 渲染。
  2. DOM 操作:僅在 mounted 或之后進行,確保 DOM 已渲染。
  3. 資源清理:在 beforeDestroy/beforeUnmount 中清理定時器、事件監聽器等。
  4. 避免重復邏輯:使用 Composition API 或 mixins 復用生命周期相關邏輯。
  5. 調試工具:利用 Vue DevTools 監控生命周期鉤子的執行情況。
  6. 性能優化:避免在生命周期鉤子中執行耗時操作,使用異步處理。

掌握 Vue 生命周期是成為一名優秀 Vue 開發者的基礎。通過合理利用生命周期鉤子,你可以更精確地控制組件行為,優化應用性能,避免常見的開發陷阱。在實際開發中,結合 Composition API 的強大功能,你可以更靈活地組織和復用代碼,打造出高質量的 Vue 應用。

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

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

相關文章

【Rust 高級trait】Rust trait的一些高級用法解密

?? 歡迎大家來到景天科技苑?? &#x1f388;&#x1f388; 養成好習慣&#xff0c;先贊后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者簡介&#xff1a;景天科技苑 &#x1f3c6;《頭銜》&#xff1a;大廠架構師&#xff0c;華為云開發者社區專家博主&#xff0c;…

聯想電腦護眼衛士與系統顏色配置(X-Rite)沖突 | 顯示設置頻繁變換色階 - 解決方案

聯想電腦護眼衛士與系統顏色配置X-Rite沖突 | 顯示設置頻繁變換色階 - 解決方案 前言方案1&#xff1a;解決聯想護眼衛士方案2&#xff1a;解決系統顏色配置(X-Rite) 前言 自帶X-Rite軟件的聯想電腦&#xff08;以拯救者Y9000P&#xff0c;Win11系統為例&#xff09;&#xff…

MySQL中SELECT查詢的執行順序

MySQL中SELECT查詢的執行順序 在日常的數據庫開發中&#xff0c;我們經常會寫各種復雜的SELECT查詢語句。然而&#xff0c;很多開發者對于MySQL實際執行這些查詢的順序并不完全了解。理解查詢的執行順序不僅有助于編寫更高效的SQL語句&#xff0c;還能幫助我們更好地優化查詢性…

es 的字段類型(text和keyword)

Text 當一個字段是要被全文檢索時&#xff0c;比如 Email 內容、產品描述&#xff0c;這些字段應該使用 text 類型。設置 text 類型以后&#xff0c;字段內容會被分析&#xff0c;在生成倒排索引之前&#xff0c;字符串會被分析器分詞。text類型的字段不用于排序&#xff0c;很…

MySQL安裝及啟用詳細教程(Windows版)

MySQL安裝及啟用詳細教程&#xff08;Windows版&#xff09; &#x1f4cb; 概述 本文檔將詳細介紹MySQL數據庫在Windows系統下的下載、安裝、配置和啟用過程。 &#x1f4e5; MySQL下載 官方下載地址 官方網站: https://dev.mysql.com/downloads/社區版本: https://dev.my…

Linux下使用nmcli連接網絡

Linux下使用nmcli連接網絡 介紹 在使用ubuntu系統的時候&#xff0c;有時候不方便使用桌面&#xff0c;使用ssh遠程連接&#xff0c;可能需要使用nmcli命令來連接網絡。本文將介紹如何使用nmcli命令連接網絡。nmcli 是 NetworkManager 的命令行工具&#xff0c;用于管理網絡連…

Python----循環神經網絡(BiLSTM:雙向長短時記憶網絡)

一、LSTM 與 BiLSTM對比 1.1、LSTM LSTM&#xff08;長短期記憶網絡&#xff09; 是一種改進的循環神經網絡&#xff08;RNN&#xff09;&#xff0c;專門解決傳統RNN難以學習長期依賴的問題。它通過遺忘門、輸入門和輸出門來控制信息的流動&#xff0c;保留重要信息并丟棄無關…

U盤掛載Linux

在 只能使用 Telnet 的情況下&#xff0c;如果希望通過 U盤 傳輸文件到 Linux 系統&#xff0c;可以按照以下步驟操作&#xff1a; &#x1f4cc; 前提條件 U盤已插入 Linux 主機的 USB 接口。Linux 主機支持自動掛載 U盤&#xff08;大多數現代發行版默認支持&#xff09;。T…

QuickBASIC QB64 支持 64 位系統和跨平臺Linux/MAC OS

QuickBASIC 的現代繼任者 QB64 已發展成為一個功能強大的開源項目&#xff0c;支持 64 位系統和跨平臺開發。以下是詳細介紹&#xff1a; 項目首頁 - QB64pe:The QB64 Phoenix Edition Repository - GitCode https://gitcode.com/gh_mirrors/qb/QB64pe 1. QB64 概述 官網&am…

【C++高級主題】命令空間(五):類、命名空間和作用域

目錄 一、實參相關的查找&#xff08;ADL&#xff09;&#xff1a;函數調用的 “智能搜索” 1.1 ADL 的核心規則 1.2 ADL 的觸發條件 1.3 ADL 的典型應用場景 1.4 ADL 的潛在風險與規避 二、隱式友元聲明&#xff1a;類與命名空間的 “私密通道” 2.1 友元聲明的基本規則…

免費開源Umi-OCR,離線使用,批量精準!

Umi-OCR&#xff08;Windows端&#xff09; Umi-OCR 是一款在 GitHub 上開源的免費 OCR 識別軟件&#xff0c;它最大的亮點就是免費、開源、支持批量處理&#xff0c;而且識別準確度很高。這款軟件不需要聯網就能用&#xff0c;非常值得推薦&#xff01; 在 OCR 識別功能方面&…

深入剖析 Docker 容器化原理與實戰應用,開啟技術新征程!

文章目錄 前言一、為什么 是Docker &#xff1f;二、Docker 容器化原理分析2.1 鏡像&#xff08;Image&#xff09;2.2 容器&#xff08;Container&#xff09;2.3 倉庫&#xff08;Registry&#xff09; 三、Docker 容器化實踐3.1 Docker安裝3.2 創建一個 Docker 鏡像3.3 運行…

黑馬程序員TypeScript課程筆記—class篇

class的基本使用 class的構造函數&#xff08;實現實例屬性的初始化&#xff09; 在使用構造函數的時候&#xff0c;小括號的后面不要指定類型&#xff0c;否則就會報錯&#xff0c;因為構造函數沒有返回值 class實例方法 class繼承&#xff08;extends&#xff09; class繼承…

PDF.js無法顯示數字簽名

問題 pdfjs加載pdf文件時無法顯示數字簽名 PDF.js 從 v2.9.359 版本開始正式支持數字簽名的渲染與顯示&#xff0c;此前版本需通過修改源代碼實現基礎兼容。 建議升級pdfjs組件大于等于v2.9.359 pdfjs歷史版本&#xff1a;https://github.com/mozilla/pdf.js/releases pdfjs…

解決VS Code誤報Java問題的終極方法

使用vscode寫java&#xff0c;發現很多Problems&#xff0c;如下圖&#xff0c;實際上并沒有問題&#xff0c;是誤報&#xff0c;怎么解決&#xff1f; 解決方案&#xff1a;disable下面這個插件&#xff0c;它和vscode-java插件沖突了導致。

【WPF】從普通 ItemsControl 到支持篩選的 ItemsControl:深入掌握 CollectionViewSource 用法

? 從普通 ItemsControl 到支持篩選的 ItemsControl&#xff1a;深入掌握 CollectionViewSource 用法 在日常 WPF 開發中&#xff0c;我們經常需要對數據進行篩選、排序、分組等操作&#xff0c;而原生的 ItemsControl 并不直接支持這些功能。本文將介紹如何通過 CollectionVi…

Mybatis Plus JSqlParser解析sql語句及JSqlParser安裝步驟

MyBatis Plus與JSqlParser&#xff1a;SQL語句解析與實戰指南 在現代Java開發中&#xff0c;SQL解析和動態SQL生成是數據庫操作中不可或缺的一部分。MyBatis Plus作為MyBatis的增強工具&#xff0c;通過JSqlParser庫實現了對SQL語句的深度解析和修改能力。本文將詳細介紹如何在…

學習路之PHP--easyswoole使用視圖和模板

學習路之PHP--easyswoole使用視圖和模板 一、安裝依賴插件二、 實現渲染引擎三、注冊渲染引擎四、測試調用寫的模板五、優化六、最后補充 一、安裝依賴插件 composer require easyswoole/template:1.1.* composer require topthink/think-template相關版本&#xff1a; "…

設計模式——享元設計模式(結構型)

摘要 享元設計模式是一種結構型設計模式&#xff0c;旨在通過共享對象減少內存占用和提升性能。其核心思想是將對象狀態分為內部狀態&#xff08;可共享&#xff09;和外部狀態&#xff08;不可共享&#xff09;&#xff0c;并通過享元工廠管理共享對象池。享元模式包含抽象享…

互聯網大廠Java求職面試:云原生微服務架構設計與AI大模型集成實戰

互聯網大廠Java求職面試&#xff1a;云原生微服務架構設計與AI大模型集成實戰 面試場景設定 人物設定&#xff1a; 李明&#xff08;技術總監&#xff09;&#xff1a;擁有15年分布式系統架構經驗&#xff0c;主導過多個億級用戶系統的重構&#xff0c;對云原生和AI融合有深…