摘要:是基于的最小實(shí)現(xiàn)。的實(shí)現(xiàn)可以參考這篇文章,我稱其為前向。而為簡(jiǎn)單起見,仍使用原生事件,采用事件委托的方式,將所有監(jiān)聽函數(shù)掛在上。的做法參考了的做法,實(shí)現(xiàn)了在上添加和刪除監(jiān)聽函數(shù)的方法,并以判斷觸發(fā)的節(jié)點(diǎn)。
Kut
Kut,一個(gè)簡(jiǎn)單的React-Like的前端視圖渲染庫(kù),是我在學(xué)習(xí)React源碼時(shí)造的輪子。Kut是基于Typescript的React最小實(shí)現(xiàn)。目前Kut支持的Top-Level方法僅有兩個(gè),即createElement、render,同時(shí)也支持組件化開發(fā),Demo在這里。
本文主要對(duì)Kut的源碼進(jìn)行說(shuō)明和記錄,項(xiàng)目地址:Github。
源碼說(shuō)明源碼都在src目錄下,目前一共9個(gè)文件,分別如下。
component.ts定義了Component類,以用于自定義組件,只是定義了一些屬性和方法,與React的Component類似。
element.tsElement是用于構(gòu)造Virtual DOM節(jié)點(diǎn)的對(duì)象,element.ts中包含一個(gè)工廠函數(shù)createElement。Element有3個(gè)屬性:type是類型,可以是DOM tag(如div等)或自定義組件(即Component子類);key用于diff時(shí)對(duì)節(jié)點(diǎn)進(jìn)行唯一區(qū)分;children是子節(jié)點(diǎn)數(shù)組,其元素可以是文本或者Element,和React的區(qū)別是,如果children只有一項(xiàng)時(shí),Kut的children仍是數(shù)組,不過(guò)只有一項(xiàng)。
instance.tsinstance.ts中包含了三種不同類型Element對(duì)應(yīng)的實(shí)例類Instance,對(duì)應(yīng)ReactComponent(注意區(qū)別Component,為避免混淆,Kut中命名為Instance),分別為文本實(shí)例TextInstance、DOM節(jié)點(diǎn)實(shí)例DOMInstance和自定義組件實(shí)例ComponentInstance。三種Instance類結(jié)構(gòu)基本類似,首先包含其對(duì)應(yīng)于DOM節(jié)點(diǎn)的唯一kutId,以方便進(jìn)行掛載、更新和卸載;而index只用于列表項(xiàng)沒指定key時(shí)使用,可忽略;key和node用于獲取DOM節(jié)點(diǎn)的key和節(jié)點(diǎn)本身。
Instance的價(jià)值主要在于mount、shouldReceive、update和unmount方法。mount方法用于遍歷VDOM樹,拼接HTML和添加監(jiān)聽函數(shù)。而shouldReceive用于判斷是否為同一節(jié)點(diǎn),若Element的type和key相同,則直接調(diào)用update更新,否則調(diào)用unmount卸載并重新mount掛載。update方法則遞歸更新以當(dāng)前節(jié)點(diǎn)為根節(jié)點(diǎn)的VDOM子樹,其中若children大于一項(xiàng)的,會(huì)使用diff算法計(jì)算其差異并調(diào)用patch進(jìn)行更新。最后,unmount方法則從DOM樹上卸載節(jié)點(diǎn),并清除引用。
diff.ts對(duì)于列表項(xiàng)更新,需要使用diff算法計(jì)算其差異。React的實(shí)現(xiàn)可以參考這篇文章,我稱其為前向diff。Kut基本的實(shí)現(xiàn)邏輯和React是相似的,但對(duì)于把元素從列表中底部挪到頂部的做法,React的前向diff會(huì)導(dǎo)致DOM更新操作過(guò)多。Kut的做法是引入后向diff,邏輯是和前向diff一致,只是方向相反,時(shí)間復(fù)雜度仍為O(n)。取前向diff和后向diff的更新操作較少者,調(diào)用patch函數(shù)對(duì)DOM進(jìn)行更新。這部分解釋我都寫在了diff.ts的注釋里了。
kut.ts/renderer.ts/constant.ts/util.ts分別是入口文件、渲染方法、一些常量和一些工具函數(shù)。其中renderer.ts中定義了Element實(shí)例化instantiate函數(shù)(即由Element生成Instance)和render函數(shù)(使用innerHTML進(jìn)行掛載),由于采用innerHTML方法進(jìn)行掛載,需要使用事件委托來(lái)處理事件,也需要使用DOM節(jié)點(diǎn)唯一kutId進(jìn)行區(qū)別,具體見event.ts。
event.tsReact為保證兼容性,具有合成事件。而Kut為簡(jiǎn)單起見,仍使用原生事件,采用事件委托的方式,將所有監(jiān)聽函數(shù)掛在document上。event.ts的做法參考了的做法,實(shí)現(xiàn)了在document上添加和刪除監(jiān)聽函數(shù)的方法,并以kutId判斷觸發(fā)的節(jié)點(diǎn)。
后續(xù)計(jì)劃最近忙著實(shí)習(xí)面試和論文暫時(shí)也沒太多時(shí)間加新功能,現(xiàn)在仍然有些bug,如componentDidMount的觸發(fā)時(shí)機(jī)不對(duì)。慢慢先打算支持異步更新和Context,起碼讓Redux能用對(duì)吧,先寫篇記錄免得后頭來(lái)看連自己都忘了(苦笑)。推薦個(gè)最近看到的關(guān)于React源碼的專欄,感覺講得還不錯(cuò)的,在這里:編程小思。
歡迎pr和stars,項(xiàng)目地址:Github。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/93827.html
答案自己谷歌或百度找。 一、來(lái)源背景 面試題是來(lái)自微博@牛客網(wǎng)發(fā)布的真實(shí)大廠前端面經(jīng)題目,我一直在收集題目長(zhǎng)期一個(gè)一個(gè)的記錄下來(lái)的,可能會(huì)有重復(fù),但基本前端的面試大綱和需要掌握的知識(shí)都在其中了,面試題僅做學(xué)習(xí)參考,學(xué)習(xí)者閱后也要用心鉆研其中的原理,重要知識(shí)需要系統(tǒng)學(xué)習(xí)、透徹學(xué)習(xí),形成自己的知識(shí)鏈。 二、532道前端真實(shí)大廠面試題 express和koa的對(duì)比,兩者中間件的原理,koa捕獲異常多種情...
答案自己谷歌或百度找。 一、來(lái)源背景 面試題是來(lái)自微博@牛客網(wǎng)發(fā)布的真實(shí)大廠前端面經(jīng)題目,我一直在收集題目長(zhǎng)期一個(gè)一個(gè)的記錄下來(lái)的,可能會(huì)有重復(fù),但基本前端的面試大綱和需要掌握的知識(shí)都在其中了,面試題僅做學(xué)習(xí)參考,學(xué)習(xí)者閱后也要用心鉆研其中的原理,重要知識(shí)需要系統(tǒng)學(xué)習(xí)、透徹學(xué)習(xí),形成自己的知識(shí)鏈。 二、532道前端真實(shí)大廠面試題 express和koa的對(duì)比,兩者中間件的原理,koa捕獲異常多種情...
答案自己谷歌或百度找。 一、來(lái)源背景 面試題是來(lái)自微博@牛客網(wǎng)發(fā)布的真實(shí)大廠前端面經(jīng)題目,我一直在收集題目長(zhǎng)期一個(gè)一個(gè)的記錄下來(lái)的,可能會(huì)有重復(fù),但基本前端的面試大綱和需要掌握的知識(shí)都在其中了,面試題僅做學(xué)習(xí)參考,學(xué)習(xí)者閱后也要用心鉆研其中的原理,重要知識(shí)需要系統(tǒng)學(xué)習(xí)、透徹學(xué)習(xí),形成自己的知識(shí)鏈。 二、532道前端真實(shí)大廠面試題 express和koa的對(duì)比,兩者中間件的原理,koa捕獲異常多種情...
摘要:經(jīng)過(guò)一番研究,我收集了個(gè)最好的庫(kù),你可以用在自己的項(xiàng)目中。該庫(kù)于年月首次推出,目前仍有近名參與者開發(fā)。超過(guò)的,是一個(gè)動(dòng)畫庫(kù),可以處理屬性單個(gè)轉(zhuǎn)換或任何屬性,以及對(duì)象。對(duì)智能設(shè)備的方向作出反應(yīng)的視差引擎快速創(chuàng)建漂亮的動(dòng)畫。 翻譯:瘋狂的技術(shù)宅原文:https://blog.bitsrc.io/11-jav... 當(dāng)我想要在網(wǎng)上找一個(gè)簡(jiǎn)潔的 Javascript 動(dòng)效庫(kù)時(shí),總是發(fā)現(xiàn)很多推...
閱讀 2565·2021-10-11 10:58
閱讀 1148·2021-09-29 09:34
閱讀 1486·2021-09-26 09:46
閱讀 3830·2021-09-22 15:31
閱讀 730·2019-08-30 15:54
閱讀 1458·2019-08-30 13:20
閱讀 1251·2019-08-30 13:13
閱讀 1486·2019-08-26 13:52