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