new Vue() 的底層工作原理

當你調用?new Vue()?時,Vue.js 會執行一系列復雜的初始化過程。讓我們深入剖析這個看似簡單的操作背后發生的事情:

1. 初始化階段

(1) 內部初始化

function Vue(options) {if (!(this instanceof Vue)) {warn('Vue is a constructor and should be called with the `new` keyword');}this._init(options); // 關鍵初始化入口
}

(2) 合并選項

  • 合并構造函數選項 (Vue.options) 和實例選項 (new Vue?傳入的選項)

  • 處理?components,?directives,?filters?等

  • 生命周期鉤子:合并為數組形式(混入時多個鉤子都會執行)

  • data:必須為函數,合并后調用函數返回新對象

  • 自定義合并:可通過?Vue.config.optionMergeStrategies?定制

// 示例:自定義選項合并策略
Vue.config.optionMergeStrategies.customOption = function (parentVal, childVal) {return childVal === undefined ? parentVal : childVal;
};

2. 核心初始化流程

(1) 生命周期開始

callHook(vm, 'beforeCreate')

(2) 響應式系統建立

initInjections(vm)   // 處理注入
initState(vm)        // 核心響應式處理
initProvide(vm)      // 處理提供

其中?initState?包含:

if (opts.props) initProps(vm, opts.props)
if (opts.methods) initMethods(vm, opts.methods)
if (opts.data) initData(vm)
if (opts.computed) initComputed(vm, opts.computed)
if (opts.watch) initWatch(vm, opts.watch)

(3) 掛載準備

callHook(vm, 'created')if (vm.$options.el) {vm.$mount(vm.$options.el) // 觸發掛載
}

3. 響應式系統深度解析

數據觀測實現

function initData(vm) {let data = vm.$options.data;data = vm._data = typeof data === 'function' ? getData(data, vm): data || {};// 數據代理:vm.xxx -> vm._data.xxxproxy(vm, '_data', key);// 核心響應式處理observe(data);
}

依賴收集原理

class Observer {constructor(value) {this.value = value;this.dep = new Dep();if (Array.isArray(value)) {// 數組的特殊處理protoAugment(value, arrayMethods);this.observeArray(value);} else {// 對象的處理this.walk(value);}}walk(obj) {Object.keys(obj).forEach(key => {defineReactive(obj, key, obj[key]);});}
}

4. 依賴收集的完整閉環

function defineReactive(obj, key, val) {const dep = new Dep();let childOb = observe(val); // 遞歸觀察子屬性Object.defineProperty(obj, key, {get() {if (Dep.target) {dep.depend();        // 收集依賴if (childOb) {childOb.dep.depend(); // 子對象依賴收集if (Array.isArray(val)) {dependArray(val);   // 數組元素依賴收集}}}return val;},set(newVal) {if (newVal === val) return;val = newVal;childOb = observe(newVal); // 新值觀察dep.notify();             // 觸發更新}});
}

5. 虛擬DOM與渲染系統

在?$mount?階段:

Vue.prototype.$mount = function(el) {el = el && query(el);// 防止重復掛載if (el === document.body || el === document.documentElement) {warn("Do not mount Vue to <html> or <body>");return this;}const options = this.$options;// 解析模板/el到render函數if (!options.render) {let template = options.template;if (template) {// 處理各種模板來源} else if (el) {template = getOuterHTML(el);}if (template) {// 編譯核心流程const { render, staticRenderFns } = compileToFunctions(template,{ ... },this);options.render = render;options.staticRenderFns = staticRenderFns;}}// 調用真正的掛載方法return mount.call(this, el);
};

5. 完整生命周期圖示

new Vue()
│
├─ beforeCreate
│   ├─ 初始化事件/生命周期
│   └─ 未初始化響應式數據
│
├─ created
│   ├─ 已完成響應式觀測
│   ├─ 計算屬性/methods/watch已配置
│   └─ 未掛載DOM
│
├─ beforeMount
│   ├─ 編譯模板為render函數
│   └─ 未執行DOM掛載
│
├─ mounted
│   ├─ 已完成DOM掛載
│   └─ $el可用
│
├─ beforeUpdate (數據變化時)
│
├─ updated
│
├─ beforeDestroy
│
└─ destroyed

6. 性能優化相關設計

  1. 異步更新隊列

    // 變更檢測是異步的
    Vue.nextTick(() => {// DOM更新完成
    })
  2. 組件級更新

    • 每個組件對應一個渲染 Watcher

    • 通過?shouldUpdate?鉤子優化

  3. 靜態樹提升

    • 編譯時標記靜態子樹

    • 跳過不必要的 diff 比對

7. 與其他設計模式的對比

特性VueReactAngular
初始化方式選項式/組合式API函數式組件裝飾器類
響應式原理getter/setter手動setStateZone.js臟檢查
變更檢測自動依賴追蹤手動/自動混合臟檢查循環
機制Vue 2.xReact 16+Angular
變更檢測細粒度依賴追蹤虛擬DOM diff臟檢查循環
更新粒度組件級纖維節點級組件級
數據綁定雙向綁定單向數據流雙向綁定
異步更新nextTick 隊列優先級調度Zone.js 控制
模板處理編譯時優化JSX 運行時處理編譯時優化

理解?new Vue()?的完整初始化過程,有助于:

  • 更高效地使用Vue框架

  • 更好地調試應用問題

  • 編寫更合理的組件代碼

  • 實現高級定制功能

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

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

相關文章

最簡安裝SUSE15SP7導致大部分命令缺失

我嘞個去~~~明明選擇Enable了ssh&#xff0c;結果也沒給裝。 俺習慣使用NetworkManager管理網絡&#xff0c;沒給裝&#xff0c;用不了nmcli和nmtui。不高興歸不高興&#xff0c;最簡安裝的話&#xff0c;也情有可原。我嘞個去去~~連ping、vi都沒有裝&#xff0c;這也太簡了。…

Vue-14-前端框架Vue之應用基礎嵌套路由和路由傳參

文章目錄 1 嵌套路由1.1 News.vue1.2 Detail.vue1.3 router/index.ts2 路由傳參2.1 query參數2.1.1 News.vue(傳遞參數)2.1.2 Detail.vue(接收參數)2.2 params參數2.2.1 router/index.ts(需要提前占位)2.2.2 News.vue(傳遞參數)2.2.3 Detail.vue(接收參數)2.3 props配置2.3.1 r…

Python網安-ftp服務暴力破解(僅供學習)

目錄 源碼在這里 需要導入的模塊 連接ftp&#xff0c;并設置密碼本和線程 核心代碼 設置線程 源碼在這里 https://github.com/Wist-fully/Attack/tree/cracker 需要導入的模塊 import ftplib from threading import Thread import queue 連接ftp&#xff0c;并設置密碼…

ES6數組的`flat()`和`flatMap()`函數用法

今天給大家分享ES6中兩個超實用的數組函數&#xff1a;flat()和flatMap()&#xff0c;學會它們能讓數組處理變得更輕松&#xff01; 1. flat()函數 1.1 基本介紹 flat()用于將嵌套數組"拍平"&#xff0c;即將多維數組轉換為一維數組。 1.2 語法 const newArray …

upload-labs靶場通關詳解:第15-16關

第十五關 getimagesize函數驗證 一、分析源代碼 function isImage($filename){$types .jpeg|.png|.gif;if(file_exists($filename)){$info getimagesize($filename);$ext image_type_to_extension($info[2]);if(stripos($types,$ext)>0){return $ext;}else{return false…

【Linux】基礎IO流

好的代碼自己會說話&#xff0c;清晰的邏輯與優雅的結構&#xff0c;是程序員與世界對話的方式。 前言 這是我自己學習Linux系統編程的第五篇筆記。后期我會繼續把Linux系統編程筆記開源至博客上。 上一期筆記是關于進程&#xff1a; 【Linux】進程-CSDN博客https://blog.csdn…

【C語言】學習過程教訓與經驗雜談:思想準備、知識回顧(二)

&#x1f525;個人主頁&#xff1a;艾莉絲努力練劍 ?專欄傳送門&#xff1a;《C語言》、《數據結構與算法》、C語言刷題12天IO強訓、LeetCode代碼強化刷題 &#x1f349;學習方向&#xff1a;C/C方向 ??人生格言&#xff1a;為天地立心&#xff0c;為生民立命&#xff0c;為…

AD8021ARZ-REEL7【ADI】300MHz低噪聲運放放大器,高頻信號處理的性價比之選!

AD8021ARZ-REEL7&#xff08;ADI&#xff09;產品解析與推廣文案 1. 產品概述 AD8021ARZ-REEL7 是 Analog Devices Inc.&#xff08;ADI&#xff09; 推出的一款 高速、低噪聲運算放大器&#xff08;Op-Amp&#xff09;&#xff0c;屬于 ADI的高性能放大器系列&#xff0c;專為…

WPF學習筆記(11)數據模板DataTemplate與數據模板選擇器DataTemplateSelector

數據模板DataTemplate與數據模板選擇器DataTemplateSelector 一、DataTemplate1. DataTemplate概述2. DataTemplate詳解 二、DataTemplateSelector1. DataTemplateSelector概述2. DataTemplateSelector詳解 總結 一、DataTemplate 1. DataTemplate概述 DataTemplate 表示數據…

【V6.0 - 聽覺篇】當AI學會“聽”:用聲音特征捕捉視頻的“情緒爽點”

系列回顧&#xff1a; 在上一篇 《AI的“火眼金睛”&#xff1a;用OpenCV和SHAP洞察“第一眼緣”》 中&#xff0c;我們成功地讓AI擁有了視覺&#xff0c;它已經能像一個嚴苛的“質檢員”一樣&#xff0c;評判我視頻的畫質和動態感。 但我的焦慮并沒有完全消除。因為我發現&a…

(5)pytest-yield操作

1. 簡介 上一篇中&#xff0c;我們剛剛實現了在每個用例之前執行初始化操作&#xff0c;那么用例執行完之后如需要清除數據&#xff08;或還原&#xff09;操作&#xff0c;可以使用 yield 來實現。fixture通過scope參數控制setup級別&#xff0c;既然有setup作為用例之前前的操…

C++中的cmath庫

在C編程中&#xff0c;數值計算是科學計算、工程應用及算法開發的基礎。cmath庫作為C標準庫的重要組成部分&#xff0c;提供了豐富的數學函數和工具&#xff0c;能夠高效處理各種數值計算任務。本文將全面解析cmath庫的核心功能&#xff0c;并通過實戰案例展示其強大威力。 一…

python包管理工具uv VS pip

在 Python 中&#xff0c;uv 和 pip 都是包管理工具&#xff0c;但它們的定位和特性有所不同。以下是主要區別&#xff1a; 1. pip&#xff08;傳統工具&#xff09; 定位&#xff1a;Python 官方的包安裝工具&#xff0c;是 Python 生態中最基礎的包管理器。特點&#xff1a;…

OpenCv基礎(C++)

1.圖像讀取與顯示 #include<opencv2/opencv.hpp> using namespace cv;Mat src imread("C:/Users/16385/Desktop/new/photo/1.jpg");//讀取圖像 Mat src imread("C:/Users/16385/Desktop/new/photo/1.jpg",IMREAD_GRAYSCALE); //將讀取的圖像轉為灰…

MySQL非阻塞創建索引的方法

文章目錄 1. Online DDL (MySQL 5.6)2. pt-online-schema-change 工具3. gh-ost 工具4. 對于MySQL 8.0注意事項 在MySQL中創建大型表索引時&#xff0c;傳統方式會阻塞表的寫操作&#xff0c;影響生產環境使用。以下是幾種非阻塞創建索引的方法&#xff1a; 1. Online DDL (My…

數字雨動畫背景

<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>數字雨動畫背景</title><style>* {m…

分布式鎖的概念與應用場景

一、分布式鎖的核心概念 分布式鎖是一種在分布式系統環境下&#xff0c;用于保證多個進程/節點對共享資源實現互斥訪問的機制。其本質是通過某種中間件&#xff08;如Redis、ZooKeeper等&#xff09;實現跨節點的鎖控制&#xff0c;確保在分布式環境中&#xff0c;同一時刻只有…

js代碼09

題目 好的&#xff0c;我們繼續。 在上一個練習中&#xff0c;我們深入探討了 this 的復雜性。你會發現&#xff0c;ES6 引入的 class 語法在很大程度上就是為了簡化 this 的使用&#xff0c;并為 JavaScript 提供一個更清晰、更熟悉的面向對象編程&#xff08;OOP&#xff0…

基于Airtest的App數據爬取實戰:突破傳統爬蟲的邊界

引言:App數據爬取的技術困境 在當今移動優先的時代,App已成為企業核心數據載體,然而??傳統爬蟲技術??在App數據獲取上面臨三大難題: ??協議層屏障??:加密HTTPS、SSL Pinning等技術阻斷中間人攻擊??渲染層障礙??:React Native、Flutter等跨平臺框架使DOM解析…

【LeetCode 熱題 100】560. 和為 K 的子數組——(解法一)前綴和+暴力

Problem: 560. 和為 K 的子數組 題目&#xff1a;給你一個整數數組 nums 和一個整數 k &#xff0c;請你統計并返回 該數組中和為 k 的子數組的個數 。子數組是數組中元素的連續非空序列。 【LeetCode 熱題 100】560. 和為 K 的子數組——&#xff08;解法二&#xff09;前綴和…