Vue中render函數(shù)調(diào)用時(shí)機(jī)與執(zhí)行細(xì)節(jié)源碼分析
背景
摸魚的時(shí)候看到有網(wǎng)友說面試問到了render函數(shù)和beforeMount鉤子哪個(gè)先觸發(fā)的問題,我印象中是先觸發(fā)beforeMount鉤子,不過本著嚴(yán)謹(jǐn)?shù)木?,拒絕印象流,還是去翻了一下Vue2源碼。
想知道結(jié)論可以直接跳到文章末尾。
解析
從$mount方法開始
$mount
方法,也就是Vue掛載的起點(diǎn)。
這里可以看到,$mount
方法其實(shí)就是調(diào)用mountCompenent
并返回執(zhí)行結(jié)果
mountCompenent發(fā)生了什么?
這里截取關(guān)鍵部分
在這里已經(jīng)有結(jié)論了,beforeMount是在render函數(shù)調(diào)用之前觸發(fā)的,不過出于好奇,還是去第七行的_render
函數(shù)里面看看細(xì)節(jié)
render函數(shù)的調(diào)用細(xì)節(jié)
轉(zhuǎn)到_render
中
可以看到_render
就是調(diào)用render
函數(shù)并返回 vnode。不過在第10行可以發(fā)現(xiàn),調(diào)用render
函數(shù)的方式并不是直接調(diào)用,而是通過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
并沒有在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代碼,也就是說如果是sfc就是getHandler_1
,否則就是hasHandler_1
,以上這兩個(gè)handler的代碼就不貼了,不然又是一個(gè)新坑=.=
總而言之,這個(gè)vm._renderProxy
就是vm
,只不過通過Proxy做了一些特殊處理。
第二個(gè)參數(shù):vm.$createElement
讀過snabbdom的應(yīng)該都認(rèn)識(shí)這個(gè)函數(shù),畢竟vue借鑒了snabbdom。源碼太長就不貼了,只要知道它最終調(diào)用_createElement
返回vnode就行。
結(jié)論
render
函數(shù)的調(diào)用時(shí)機(jī)是在beforeMount
之后和mounted
之前。- 通過call將
render
函數(shù)的this綁定到了vm,并且會(huì)根據(jù)Proxy的支持情況和是否是SFC來做一些不同的處理。 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í)行的資料請關(guān)注腳本之家其它相關(guān)文章!
- vue3通過render函數(shù)實(shí)現(xiàn)菜單下拉框的示例
- vue中的render函數(shù)、h()函數(shù)、函數(shù)式組件詳解
- Vue render函數(shù)使用詳細(xì)講解
- 簡單談一談Vue中render函數(shù)
- vue中使用render封裝一個(gè)select組件
- Vue 2閱讀理解之initRender與callHook組件詳解
- vue語法之render函數(shù)和jsx的基本使用
- vue3中的render函數(shù)里定義插槽和使用插槽
- VUE3中h()函數(shù)和createVNode()函數(shù)的使用解讀
- Vue.js3.2的vnode部分優(yōu)化升級使用示例詳解
- Vue.js之VNode的使用
- vue中?render?函數(shù)功能與原理分析
相關(guān)文章
vite中的glob-import批量導(dǎo)入的實(shí)現(xiàn)
本文主要介紹了vite中的glob-import批量導(dǎo)入的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07element組件el-date-picker禁用當(dāng)前時(shí)分秒之前的日期時(shí)間選擇
本文主要介紹了element組件el-date-picker禁用當(dāng)前時(shí)分秒之前的日期時(shí)間選擇,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01vue組件屬性(props)及私有數(shù)據(jù)data解析
這篇文章主要介紹了vue組件屬性(props)及私有數(shù)據(jù)data解析,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10vue打包c(diǎn)hunk-vendors.js文件過大導(dǎo)致頁面加載緩慢的解決
這篇文章主要介紹了vue打包c(diǎn)hunk-vendors.js文件過大導(dǎo)致頁面加載緩慢的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04使用vNode實(shí)現(xiàn)給列表字段打標(biāo)簽
這篇文章主要為大家介紹了使用vNode實(shí)現(xiàn)給列表字段打標(biāo)簽示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09解決ant-design-vue中menu菜單無法默認(rèn)展開的問題
這篇文章主要介紹了解決ant-design-vue中menu菜單無法默認(rèn)展開的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10vue使用video插件vue-video-player的示例
這篇文章主要介紹了vue使用video插件vue-video-player的示例,幫助大家更好的理解和使用vue插件,感興趣的朋友可以了解下2020-10-10