摘要:流程圖盜用一下官網關于生命周期的圖,對照之前的內容梳理一下對照上面的分析基本上可以找到各個鉤子函數的位置,下面那個銷毀的我就沒用做分析了。。。
vue整體框架和主要流程分析
之前對看過比較多關于vue源碼的文章,但是對于整體框架和流程還是有些模糊,最后用chrome debug對vue的源碼進行查看整理出這篇文章。。。。
本文對vue的整體框架和整體流程進行簡要的分析,不對某些具體的細節進行分析,所有需要對vue有初步的認識,包括對Object.defineProperty、虛擬DOM有一定了解,本文不會對Object.defineProperty、虛擬DOM的原理和細節進行分析。
vue大體可以分兩個部分:
1.采用Object.defineProperty進行數據的雙向綁定;
2.采用虛擬DOM技術進行視圖渲染;
vue構造函數調用了this._init(options)方法,這個方法在initMixin中,如上圖所示,進入initMixin
initMixin主要完成數據的初始化和視圖的初始化:
1.數據初始化主要是數據的observe,在上圖的initState中進行;
2.視圖的初始化在vm.$mount(vm.$options.el),其中vm為Vue的實例,watcher的設置也是在vm.$mount(vm.$options.el)中完成的;
我們可以看到這里定義了beforeCreated和created這兩個鉤子函數。
接著上面我們看看數據初始化都做了什么,進入initState
這里我們主要對數據進行操作的是initData,傳入的是vm,我們來具體看看initData:
我們先忽略前面的一些邏輯判斷,主要看兩個地方:
1.數據代理,主要是將_data的數據代理到vm上,這樣的話可以直接對vm上的數據進行修改;
2.數據observe,傳入data;
我們先看看vue怎么對數據進行observe的,進入observe
在observe里返回的是ob,也就是Observer類的實例,我們看看Observer類是怎么定義的,進入Observer類
如上圖在對data進行observe時對數組進行了特殊的處理,這塊我們先不看,先看一般情況下的處理,即調用this.walk(value)
walk主要對data的屬性進行遍歷,進入defineReactive
可以看到Object.defineProperty是在這里對屬性設置get和set的,其中get主要進行依賴收集,其實就是在收集視圖渲染的watcher,后面會提到,set主要是數據更新時進行視圖的更新
至此,數據的初始化就完成了,從上面的分析來看,數據的初始化主要的工作就是對數據進行observe。
接著上面,在vue入口那里,我們知道視圖的掛載主要是調用了vm.$mount(vm.$options.el)
如圖,所以我們進入vm.$mount,看看里面都干了啥,在源碼里面有兩處地方涉及到$mount
這是第一處,就是return mountComponent
這是第二處,上面兩個圖是一起的,屏幕大小有限,所以截了兩個圖。。。
咱們看看第二處,里面做了一個處理,就是將template編譯成render函數,在vue的教程里有render函數的使用,這里我們可以看出我們在組件里定義render函數會比定義template快,因為在定義template的組件掛載時多了一步將template編譯成render函數;
第二處的return 還是調用了第一處,所以我們看看第一處調用的mountComponent方法,進入mountComponent
上面兩個圖是一起的,屏幕大小有限,所以截了兩個圖。。。
這里我們可以看到定義了兩個鉤子beforeMount和mount,中間調用了watcher,我們看一下這里watcher的定義,這里標注的不太好,擋住了。。。我們看看watcher的這行代碼:
vm._watcher=new Watcher(vm,updateComponent,noop)
我們可以看到Watcher類主要傳入了vm,updateComponent,noop三個參數,其中updateComponent的主要作用是將虛擬DOM轉化為真實的DOM并進行掛載,具體的細節下面在討論,我們下面看看Watcher類是怎么定義的,進入Watcher
這里我們注意兩個地方,一個是this.getter的定義,這里就是上面傳進來的updateComponent,還有就是執行this.get(),我們進入這個get方法
這里我們看到首先收集的依賴是當前watcher實例,然后調用getter方法也就是updateComponent方法,之前我們對updateComponent方法的作用進行了簡單的說明,這里我們具體看看updateComponent都干了啥,進入updateComponent:
這里調用了vm._update方法,其中傳入的參數有vm._render(),_render函數主要的作用是產生虛擬DOM,進入_update
這里主要是將虛擬DOM轉化為真實DOM并進行掛載,分兩種情況,分別是有舊的虛擬DOM和無舊的虛擬DOM,對應初始化時調用還是數據更新時調用,這里定義了一個鉤子beforeUpdate
到這里,視圖的初始化和掛載也結束了,下面看看數據變化時視圖是如何更新的
接著上面我們看看數據變化時視圖是怎么變化的,在數據初始化的時候,我們知道數據變化時將觸發set方法,如下圖:
上圖可以看出,set最后調用了dep.notify,進入notify
如上圖,notify主要將收集的依賴,也就是收集的所有watcher,調用所有watcher的update方法,我們看看watcher的updata方法干了啥
這里就是調用了queueWatcher,進入queueWatcher
這里采用隊列異步更新,就是講=將watcher push進隊列queue中,然后執行nextTick方法,進入nextTick
上面兩個圖是一起的,屏幕大小有限,所以截了兩個圖。。。
這個部分有點難看,cb為傳入的flushSchedulerQueue函數,執行timerFunc,將nextTickHander加入異步隊列,執行nextTickHander,執行cb,既執行flushSchedulerQueue,進入flushSchedulerQueue
上面兩個圖是一起的,屏幕大小有限,所以截了兩個圖。。。
主要看watcher.run(),進入watcher.run
執行了this.get(),即進入前面數據渲染和掛載的地方
到這里,vue整個的執行流程基本就結束了。
盜用一下vue官網關于vue生命周期的圖,對照之前的內容梳理一下:
對照上面的分析基本上可以找到各個鉤子函數的位置,下面那個銷毀的我就沒用做分析了。。。
大家有興趣的話可以關注一下我的博客
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84501.html
摘要:哪吒別人的看法都是狗屁,你是誰只有你自己說了才算,這是爹教我的道理。哪吒去他個鳥命我命由我,不由天是魔是仙,我自己決定哪吒白白搭上一條人命,你傻不傻敖丙不傻誰和你做朋友太乙真人人是否能夠改變命運,我不曉得。我只曉得,不認命是哪吒的命。 showImg(https://segmentfault.com/img/bVbwiGL?w=900&h=378); 出處 查看github最新的Vue...
摘要:是目前唯一一個支持同步調用的跨平臺年度上最多的個項目前端掘金年接近尾聲,在最近的幾篇文章中,會整理總結一些年度開源項目。 JS 全棧教程 - 前端 - 掘金本課程是基于阮一峰的 js 全棧教程的視頻版本,免費供大家觀看... 2016 年 10 個最佳的 CodePen 作品 - 前端 - 掘金說到 CodePen,前端開發者們肯定不會陌生。如果說 Dribbble 是設計師們聚集的圣...
好久沒更新過Vue的小文章,上次做了一個基于Vue+Mint-ui的移動端AppDemo,集成了推送功能,然后通過cordova打包生成apk,移動端表現還不錯,今天把這個小東西分享出來,希望有更多的小伙伴能夠用Vue去做一些有意思的東西,本人才疏學淺,有說的不對的地方,還請大家多多指教。下面按照慣例放上demo地址和源碼地址,希望大家能給我點下star:Demo(進去需要先注冊才能登錄,用的lo...
閱讀 3667·2021-10-11 11:09
閱讀 1337·2021-09-24 10:35
閱讀 3422·2021-07-29 13:48
閱讀 460·2019-08-30 13:15
閱讀 2511·2019-08-30 12:53
閱讀 3183·2019-08-30 12:44
閱讀 2711·2019-08-29 16:57
閱讀 957·2019-08-29 12:26