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