摘要:這個大概是的鉤子吧在每一次插入操作的時候都將節(jié)點(diǎn)這類型方法可以看出來是在調(diào)用對應(yīng)的方法因?yàn)殚_始的時候就導(dǎo)入進(jìn)來了插入節(jié)點(diǎn)操作的時候都需要加入子節(jié)點(diǎn)有子元素也就是的時候遞歸調(diào)用循環(huán)子節(jié)點(diǎn)生成對應(yīng)著一些操作之后都要觸發(fā)鉤子函數(shù)。
snabbdom
本文的snabbdom源碼分析采用的是0.54版本(即未用ts重寫前的最后一版)
前期了解snabbdom被用作vue的虛擬dom。本文的一個目的就是對于進(jìn)入vue源碼預(yù)備。
本文大致講解,而不會完全細(xì)化至代碼行數(shù)講解
modules
helper
h.js
htmldomapi.js
is.js
snabbdom.js
thunk.js
vnode.js
vnode.js說白了就是返回一個數(shù)據(jù)表示dom結(jié)構(gòu)的數(shù)據(jù)對象
h.js則是對多重有子結(jié)構(gòu) text節(jié)點(diǎn)之類的數(shù)據(jù)對象進(jìn)行在再處理
返回一個解析好的vnode
一些dom操作的api封裝
結(jié)合到后面做vnode渲染到真實(shí)dom的操作
is.js 兩個工具函數(shù) 一個是是否為數(shù)組 一個是是否為基本類型 也就是數(shù)字string這些文本節(jié)點(diǎn)
里面放的則是一些對應(yīng)的數(shù)據(jù)結(jié)構(gòu)上例如property attribute之類的輔助操作
attributes
里面用來更新節(jié)點(diǎn)的屬性
基本的套路都是一個for in迭代 然后內(nèi)部判斷patch 判斷是否需要更新亦或者是刪除 如果存在屬性的話 且不同肯定是更新 如果新有了 舊的沒有就增加 新沒有了舊還有 對于一些屬性直接設(shè)置false 或者是賦空即可
class.js
這里也是一些利用classList做快速增加修改刪除節(jié)點(diǎn)上的class的操作
基本簡單的判斷就是這種套路
datatset
設(shè)置節(jié)點(diǎn)屬性值
eventlistener
看源碼可以發(fā)現(xiàn) 事件綁定這一步傳入的參數(shù)實(shí)際上是被包裝的
利用函數(shù)封裝了一層handleevent
handleevent里面實(shí)際上是觸發(fā)invokeHandler
那么從源碼可以看出 實(shí)際上觸發(fā)dom節(jié)點(diǎn)的綁定事件實(shí)際上是在觸發(fā)
綁定在上下文為vnode的觸發(fā)器上。
props設(shè)置節(jié)點(diǎn)這個props是需要鍵值對的。一般自定義屬性值在這里聲明好一些,設(shè)置checked selected因?yàn)閮?nèi)部有一個booleanarray 其實(shí)有綁定的話只是做
property能夠從attribute中得到同步;
attribute不會同步property上的值;
模擬動畫幀 用requestAnimationFrame不兼容則用setTimeout
requestAnimationFrame的好處是它的刷新頻率會與瀏覽器一致
setTimeout則有時候可能出現(xiàn)丟失的情況
內(nèi)部封裝一個兩層的調(diào)用來使用,大概是兩幀的意思
如果沒有delayed或者remove直接更新style即可
設(shè)置節(jié)點(diǎn)被destory時候的style
設(shè)置刪除效果也就是調(diào)用自定義的remove鉤子函數(shù)。如果沒有的話就調(diào)用全局的
這些定義都是根據(jù)api閱讀結(jié)合源碼發(fā)現(xiàn)的
remove鉤子執(zhí)行后才會刪除樣式
這塊是在網(wǎng)上看的源碼解讀
因?yàn)閐iff算法應(yīng)該是一個vitrual dom實(shí)現(xiàn)的重點(diǎn)了
createKeyToOldIdx 給舊節(jié)點(diǎn)設(shè)置key用于比對
// create => style,class,dataset,eventlistener,props,hero
// update => style,class,dataset,eventlistener,props,hero
// remove => style
// destory => eventlistener,style,hero
// pre => hero
// post => hero
這是一些鉤子函數(shù)的使用api吧
init做一些模塊的初始化 還有全局鉤子的初始化
傳入一個節(jié)點(diǎn) 然后對這個節(jié)點(diǎn)進(jìn)行操作提取 轉(zhuǎn)換成vnode數(shù)據(jù)對象
// remove攔截器 style里面提及的
// 對remove鉤子回調(diào)做減法然后才刪除節(jié)點(diǎn)
vnode映射真實(shí)節(jié)點(diǎn)
看到這里的時候?qū)nsertedVnodeQueue很不懂 究竟要干嘛
然后突然想明白了。這個大概是inserted的鉤子吧- -
在每一次插入操作的時候都將節(jié)點(diǎn)insert
api.這類型方法可以看出來是在調(diào)用對應(yīng)modules的方法
因?yàn)殚_始的時候就導(dǎo)入進(jìn)來了
插入節(jié)點(diǎn)操作的時候都需要加入insertedVnodeQueue
子節(jié)點(diǎn)有子元素 也就是children的時候遞歸調(diào)用循環(huán)子節(jié)點(diǎn)生成tree
對應(yīng)著一些操作之后都要觸發(fā)鉤子函數(shù)。
以前并不清楚鉤子函數(shù)生命周期觸發(fā)原理,這次倒是見識了
invokeDestroyHook 手動觸發(fā)destroy鉤子 先觸發(fā)vnode的鉤子 在觸發(fā)全局鉤子 再遞歸觸發(fā)子節(jié)點(diǎn)的鉤子
removeVnodes remove操作 因?yàn)橐沟胷emove鉤子觸發(fā)后才刪除節(jié)點(diǎn)
updateChildren patchVnode 最主要的diff算法
利用前后索引的方式
進(jìn)行對兩樹的遍歷patch 復(fù)雜度是O(n)
因?yàn)楸容^都是在同層做比較對比patch
起點(diǎn)在patchVnode 然后patch過程updateChildren 然后調(diào)用updateChildrens
一個分段的偽遞歸
而當(dāng)索引不生效 這個時候則采用傳統(tǒng)的key-index比對
網(wǎng)上的一些simple vitrual dom教程
實(shí)現(xiàn)的是基于深度遍歷做list diff
然后取得節(jié)點(diǎn)的變化
在做對應(yīng)操作 。
snabbdom的patch等等 都是基于數(shù)據(jù)對象做的。
而一些vitrual的實(shí)現(xiàn)是基于樹的patch
virtual-dom的一個好處就是讓我們可以從繁雜無章的dom操作中解脫,利用js對象的形式映射到dom,從而操作js數(shù)據(jù)操作dom
所謂的性能其實(shí)還是得看你怎么用,大片的修改dom不見得virtual dom就有多好用。
打算也實(shí)現(xiàn)個simple dom 占坑~~(當(dāng)然在path diff算法上可能不存在優(yōu)化了)(占坑占坑)
snabbdom也是vue使用的virtual dom 庫,emmm之后可以看看vue是怎么結(jié)合使用snabbdom的。
撒花。thanks
如果有需要詳細(xì)代碼解析的朋友可以聯(lián)系我獲取。
snabbdom源碼地址
不錯的snabbdom源碼解讀
本人博客
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/95066.html
摘要:閱讀源碼的時候,想了解虛擬結(jié)構(gòu)的實(shí)現(xiàn),發(fā)現(xiàn)在的地方。然而慢慢的人們發(fā)現(xiàn),在我們的代碼中布滿了一系列操作的代碼。源碼解析系列源碼解析一準(zhǔn)備工作源碼解析二函數(shù)源碼解析三對象源碼解析四方法源碼解析五鉤子源碼解析六模塊源碼解析七事件處理個人博客地址 前言 虛擬 DOM 結(jié)構(gòu)概念隨著 react 的誕生而火起來,之后 vue2.0 也加入了虛擬 DOM 的概念。 閱讀 vue 源碼的時候,想了解...
介紹 這里是 typescript 的語法,定義了一系列的重載方法。h 函數(shù)主要根據(jù)傳進(jìn)來的參數(shù),返回一個 vnode 對象 代碼 代碼位置 : ./src/h.ts /** * 根據(jù)選擇器 ,數(shù)據(jù) ,創(chuàng)建 vnode */ export function h(sel: string): VNode; export function h(sel: string, data: VNodeData...
摘要:對象是一個對象,用來表示相應(yīng)的結(jié)構(gòu)代碼位置定義類型定義類型選擇器數(shù)據(jù),主要包括屬性樣式數(shù)據(jù)綁定時間等子節(jié)點(diǎn)關(guān)聯(lián)的原生節(jié)點(diǎn)文本唯一值,為了優(yōu)化性能定義的類型定義綁定的數(shù)據(jù)類型屬性能直接用訪問的屬性樣式類樣式數(shù)據(jù)綁定的事件鉤子創(chuàng)建對象根據(jù)傳入的 vnode 對象 vnode 是一個對象,用來表示相應(yīng)的 dom 結(jié)構(gòu) 代碼位置 :./src/vnode.ts 定義 vnode 類型 /** ...
摘要:元素從父節(jié)點(diǎn)刪除時觸發(fā),和略有不同,只影響到被移除節(jié)點(diǎn)中最頂層的節(jié)點(diǎn)在方法的最后調(diào)用,也就是完成后觸發(fā)源碼解析系列源碼解析一準(zhǔn)備工作源碼解析二函數(shù)源碼解析三對象源碼解析四方法源碼解析五鉤子源碼解析六模塊源碼解析七事件處理個人博客地址 文件路徑 : ./src/hooks.ts 這個文件主要是定義了 Virtual Dom 在實(shí)現(xiàn)過程中,在其執(zhí)行過程中的一系列鉤子。方便外部做一些處理 /...
摘要:閑聊在學(xué)的過程中,虛擬應(yīng)該是聽的最多的概念之一,得知其是借鑒進(jìn)行開發(fā),故習(xí)之。以我的觀點(diǎn)來看,多個相同元素渲染時,則需要為每個元素添加值。 閑聊:在學(xué)vue的過程中,虛擬dom應(yīng)該是聽的最多的概念之一,得知其是借鑒snabbdom.js進(jìn)行開發(fā),故習(xí)之。由于我工作處于IE8的環(huán)境,對ES6,TS這些知識的練習(xí)也只是淺嘗輒止,而snabbdom.js從v.0.5.4這個版本后開始使用TS...
閱讀 3843·2021-11-11 10:58
閱讀 2642·2021-09-22 15:43
閱讀 2935·2019-08-30 15:44
閱讀 2313·2019-08-30 13:08
閱讀 1921·2019-08-29 17:28
閱讀 980·2019-08-29 10:54
閱讀 756·2019-08-26 11:46
閱讀 3576·2019-08-26 11:43