Vue中render函數(shù)調(diào)用時(shí)機(jī)與執(zhí)行細(xì)節(jié)源碼分析
背景
摸魚(yú)的時(shí)候看到有網(wǎng)友說(shuō)面試問(wèn)到了render函數(shù)和beforeMount鉤子哪個(gè)先觸發(fā)的問(wèn)題,我印象中是先觸發(fā)beforeMount鉤子,不過(guò)本著嚴(yán)謹(jǐn)?shù)木瘢芙^印象流,還是去翻了一下Vue2源碼。
想知道結(jié)論可以直接跳到文章末尾。
解析
從$mount方法開(kāi)始
$mount方法,也就是Vue掛載的起點(diǎn)。

這里可以看到,$mount方法其實(shí)就是調(diào)用mountCompenent并返回執(zhí)行結(jié)果
mountCompenent發(fā)生了什么?
這里截取關(guān)鍵部分

在這里已經(jīng)有結(jié)論了,beforeMount是在render函數(shù)調(diào)用之前觸發(fā)的,不過(guò)出于好奇,還是去第七行的_render函數(shù)里面看看細(xì)節(jié)
render函數(shù)的調(diào)用細(xì)節(jié)
轉(zhuǎn)到_render中

可以看到_render就是調(diào)用render函數(shù)并返回 vnode。不過(guò)在第10行可以發(fā)現(xiàn),調(diào)用render函數(shù)的方式并不是直接調(diào)用,而是通過(guò)call方法,第一個(gè)參數(shù)是 render函數(shù)的this環(huán)境,第二個(gè)參數(shù)就是在render函數(shù)中的參數(shù)h。
第一個(gè)參數(shù):vm._renderProxy
從上一部分得知,vm._renderProxy就是render函數(shù)的this環(huán)境,轉(zhuǎn)到相應(yīng)源碼看看。

可以看到,vm._renderProxy要么是vm本身,要么是vm的一個(gè)Proxy,據(jù)Proxy API的支持情況而定。如果是后者,情況就復(fù)雜一些:如果 options.render._withStripped為真,則Proxy的handler為getHandler_1,否則是hasHandler_1??墒沁@個(gè)options.render._withStripped并沒(méi)有在Vue源碼中出現(xiàn),最后在負(fù)責(zé)編譯sfc的 compiler-sfc.js中找到了。
// compiler-sfc.js // mark with stripped (this enables Vue to use correct runtime proxy // detection) code += `render._withStripped = true`;
變量code就是sfc編譯后的js代碼,也就是說(shuō)如果是sfc就是getHandler_1,否則就是hasHandler_1,以上這兩個(gè)handler的代碼就不貼了,不然又是一個(gè)新坑=.=
總而言之,這個(gè)vm._renderProxy就是vm,只不過(guò)通過(guò)Proxy做了一些特殊處理。
第二個(gè)參數(shù):vm.$createElement
讀過(guò)snabbdom的應(yīng)該都認(rèn)識(shí)這個(gè)函數(shù),畢竟vue借鑒了snabbdom。源碼太長(zhǎng)就不貼了,只要知道它最終調(diào)用_createElement返回vnode就行。
結(jié)論
render函數(shù)的調(diào)用時(shí)機(jī)是在beforeMount之后和mounted之前。- 通過(guò)call將
render函數(shù)的this綁定到了vm,并且會(huì)根據(jù)Proxy的支持情況和是否是SFC來(lái)做一些不同的處理。 render函數(shù)的參數(shù)h的作用是創(chuàng)建vnode
以上就是Vue中render函數(shù)調(diào)用時(shí)機(jī)與執(zhí)行細(xì)節(jié)源碼分析的詳細(xì)內(nèi)容,更多關(guān)于Vue render函數(shù)調(diào)用執(zhí)行的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- vue3通過(guò)render函數(shù)實(shí)現(xiàn)菜單下拉框的示例
- vue中的render函數(shù)、h()函數(shù)、函數(shù)式組件詳解
- Vue render函數(shù)使用詳細(xì)講解
- 簡(jiǎn)單談一談Vue中render函數(shù)
- vue中使用render封裝一個(gè)select組件
- Vue 2閱讀理解之initRender與callHook組件詳解
- vue語(yǔ)法之render函數(shù)和jsx的基本使用
- vue3中的render函數(shù)里定義插槽和使用插槽
- VUE3中h()函數(shù)和createVNode()函數(shù)的使用解讀
- Vue.js3.2的vnode部分優(yōu)化升級(jí)使用示例詳解
- Vue.js之VNode的使用
- vue中?render?函數(shù)功能與原理分析
相關(guān)文章
vue vue-Router默認(rèn)hash模式修改為history需要做的修改詳解
今天小編就為大家分享一篇vue vue-Router默認(rèn)hash模式修改為history需要做的修改詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09
詳解vue開(kāi)發(fā)中調(diào)用微信jssdk的問(wèn)題
這篇文章主要介紹了vue開(kāi)發(fā)中調(diào)用微信jssdk的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
Vuejs如何通過(guò)Axios請(qǐng)求數(shù)據(jù)
這篇文章主要介紹了Vuejs如何通過(guò)Axios請(qǐng)求數(shù)據(jù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04
vuejs使用axios異步訪問(wèn)時(shí)用get和post的實(shí)例講解
今天小編就為大家分享一篇vuejs使用axios異步訪問(wèn)時(shí)用get和post的實(shí)例講解,具有很好的參考價(jià)值。希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
關(guān)于vue項(xiàng)目proxyTable配置和部署服務(wù)器的問(wèn)題
這篇文章主要介紹了關(guān)于vue項(xiàng)目proxyTable配置和部署服務(wù)器的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04
vue,angular,avalon這三種MVVM框架優(yōu)缺點(diǎn)
本文給大家具體分析了下vue,angular,avalon這三種MVVM框架優(yōu)缺點(diǎn),十分的細(xì)致全面,有需要的小伙伴可以參考下2016-04-04
vue項(xiàng)目?jī)?yōu)雅實(shí)現(xiàn)自動(dòng)引入組件的方法詳解
在我們寫(xiě)vue項(xiàng)目的時(shí)候,都會(huì)引入一些組件庫(kù),有時(shí)候有可能還不止一個(gè)組件庫(kù),那么如何優(yōu)雅的實(shí)現(xiàn)自動(dòng)引入組件呢,下面小編就來(lái)和大家詳細(xì)講講吧2023-09-09

