JavaScript進階(三十五):編譯的準備工作

上篇博客,我們已經完成了最基本的抽象虛擬 DOM 樹。所以接下來,我們剩下要做的事,就變的非常的簡單了。

我們先把一些其他的東西來考慮考慮。

首先,現在我的這些節點,全是死的,這肯定不行呀。我需要做什麼呀?我需要它們能夠編譯。

所以說白了,在我們的 VElement 這裏,其實應該還有一級。

 

一般我們最上層是 VNode 節點,它實際上就是一個類型,沒提供太多功能。

說白了,VNode 它主要是提供一個父類型用的,這樣將來比較好判斷,比如我看它是不是 instanceof VNode,就知道它是不是我的東西了。

 

然後這個 VText,其實也沒太多東西可言,但是 VText,它要不要做到,把一個這樣的東西:

"xyzqwe {{a+b}} fghdef" 給編譯成 "xyzqwe 17 fghdef",如果 a=12,b=5 的話。

肯定是需要做到這一點的,所以 VText 它有簡單的功能,就是一個編譯。

 

以及還有一個 VElement,我希望它具有簡單的編譯功能。

比如我們加了個 :title="a",那麼這時候它要給我編譯成 title="12",以及這個 VElement,我不希望它具備複雜的功能,它就是一個,對這種普通的 HTML 元素的映射,這就夠了。

爲什麼這樣呢?原因很簡單。

因爲,一個類越大,越不好維護,而且性能也越低,所以我們讓它單純一點,它就只是描述一個節點,就夠了。

 

而我個人更喜歡的是,在 VElement 這裏在搞一級,我叫它 VComponent,就是一個組件了。

這個組件,它具備各種東西,比如它可以有各種各樣的方法和數據。

那麼這個怎麼做呢?

首先,我們在加一個 js 文件,我叫它 VComponent.js:

我們希望的很簡單,就是 VComponent,它上面有數據,有事件,有監聽器,有 computed,等等,都是在它身上,它是一個帶有功能的東西。

說白了,在 VElement 上面,它是不帶數據的,什麼都沒有。

而 VComponent,纔是我們真正要的東西。

 

然後這時候,我需要一個 options,因爲它裏面有各種各樣的東西。

然後我具體怎麼用它呢?大概這麼來用,我希望是這樣的:

那麼接下來,我的 VComponent 這個東西,是不是應該繼承自 VElement?

比如說,我這有一個普通的 vue 組件:

我們先不管 script 和 style 怎麼寫,我們寫的 template,這個組件最終,我們要不要讓它進到頁面裏面去?

肯定的,組件最終一定是要進到頁面裏面去的。

那大家有沒有注意過一個事,就是我真的把這樣一個組件,放到頁面裏之後,它有 template 這級嗎?

沒有。它留下的,只是 div 這一級。

換句話說,其實我的一個組件 VComponent,它到了最後,真正進到頁面裏面,表現出來的,也是一個元素。

 

所以我們就可以得出一結論:VComponent 是繼承自 VElement 的,它也是一個元素。

而事實上,我們寫起來的,也是這樣,比方說我們假設有的 cmp 組件:

那這個 cmp 是元素嗎?它也是。

所以 VComponent 應該是繼承自 VElement 的,因爲它也是一個元素。

 

那麼到現在,別的先不管,既然是繼承了,我們第一件事幹啥?

super,一切繼承,在根上都是 super:

因爲你不用 super 的話,是沒辦法用 this 的。

super 完了之後,它纔有 this 的。

 

然後接下來有個小問題,父級 super,它裏面有啥參數?

我們都知道 VElement,它裏面就一個參數,dom。

那這個是不是就對應於,我的那個 el:

但是在 VElement 那邊,它是一個真 DOM。

而在我這邊,它可能是個 DOM,也有可能是個選擇器。

所以這裏也要再來一次判斷:

super 只要放在所有的 this 之前就可以了。

 

然後,我們需要考慮下,接下來要做點什麼。

沒別的,我們在 new VComponent 傳的參數,得把它們給存起來:

首先,我們需要處理的是 el 和 data,這兩個我們肯定是需要的。

但是我們需要做響應式,所以需要一個 proxy,並且需要它的 get,set:

set 設置完之後,我們是需要渲染的,既然說到渲染這個話題了,那麼 VText 能不能渲染?能。

VText 的渲染,其實就是把這個文本里面,所夾帶的數據,給它轉換成一個真實的東西。

比如說,我在文本里面加一個 {{ a }},對於這來說,它應該替換成 12:

所以,VText 是要有 render 的。

以及 VElement 要不要渲染?肯定的,我們是需要把那一大堆 z- 開頭的屬性,給替換成真的,所以也需要渲染。

那既然如此,我們就可以直接在父級 VNode 裏面放個 render:

當然,這個 VNode,其實我們並沒打算真的讓它去擔任什麼樣的東西。

所以理論上它是不應該被渲染的,如果出現 VNode 被渲染的情況,其實是不對的。

所以這時候,如果你把一個抽象節點渲染出來了,我們就需要報錯:

因爲一旦執行到 VNode 身上的 render,就說明你某一級子類裏面,沒寫東西,那就不對了。

所以,VText 需要 render,以及 VElement 和 VComponent 也需要 render:

接下來呢,這時候我們就需要觸發自己的那個 render:

以及呢,這事還沒完,前面的博客有說過,這樣寫 this 是不對的,所以我們需要在外面搞一層:

以及,還有一個 methods,我們也要把它存起來:

那麼到這爲止,該有的,一切都差不多了。

下篇博客,我們就需要開始做很多的事了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章