JavaScript進階(三十三):如何把真實的 DOM 抽象成虛擬 DOM 樹(三)

這篇博客,我們來完善下獲取指令的方法 createDirectives。

然後,從我們獲取的 attributes ,全都一視同仁嗎?不是的,有些東西就是特殊。

所以我們的第一步,得先判斷下,它是不是一個指令。

這個很簡單,因爲是有標準的,就兩種標準,要麼 z- 開頭,要麼 : 開頭,當然這個 : 它是 z-bind 的簡稱。

 

所以我們在 createDirectives 裏面需要做的就是這些事,那麼,我們就稍微的做個循環:

我這裏的 attrs,已經不是系統的那個 attributes 了,這是我們自己的那個 this._attrs,所以我們纔可以用 for in 循環來處理它。

以及,我們循環自己的 attrs,肯定比循環系統的那個 attributes 要快很多,這個也是我們所需要的。

 

然後接下來,我們在循環的過程當中,就來看看,如果是以冒號開頭的,那我就要了:

另外還有一種情況,就是以 z- 開頭的:

那麼這兩種情況爲什麼要分開處理呢?

原因很簡單,因爲這個冒號,我實際上來說,需要給它單獨列一個。

當然順便一說,這個 directives,其實它並不是簡簡單單就是一個名字,一個值就完了,我們來看看它都有什麼樣的變化。

 

首先,比方說,我們關注的什麼?

第一,我們關注它是個什麼指令。有可能是個 if 指令,也有可能是個 show 指令,或者是個 bind 指令:

第二,比方說 bind 指令,它其實是有參數的:

所以你會發現一部分的指令它是有參數的,bind 就是其中的一個,它冒號的後面,就是它指令本身的參數。

比如 z-bind:value="aaa",它的參數就是這個 value。

以及還有一個,就是它的值:

比如 z-bind:value="aaa",它的值就是 aaa。

 

所以接下來,我們在冒號的時候,就需要來做點手腳,我們主要關注幾件事。

第一,這個指令,它本身的類型。

比方說你是個 bind,或者你是個 if,還是個 for,這都可以。

第二,就是這個指令本身的參數。

比方說 z-bind:value="aaa",那這時候,它的參數就是 value。

當然,還有的指令,比方說 z-if,z-show,它們就沒有參數,這也無所謂,我們空着就行了。

第三,就是指令的值,這個對應的就很多了。

 

既然關注這三件事,那我們就給它取 3 個名字。

指令的類型,就叫 name。

指令的參數,就叫 arg。

指令的值,就叫 value。

那麼這幾個東西都有了之後,如果是冒號開頭,那麼我就給它 push 一個新的值:

首先,name,就是一個 bind。

其次,arg 就是冒號後面東西。所以這時候我們就得從第一位開始,因爲要把第零位的冒號給挑出去。

然後,value,就是 attrs 所對應的值。

 

然後以及,還有一種,就是以 z- 來開頭的,這種需要稍微的來處理下。

首先,我們這有沒有可能有參數,比如 z-xxx:abc?是有可能的,萬一將來還有一些自定義的指令呢,這誰知道。

所以在這,我需要用冒號來 split 一下,然後我們會得到兩個東西,一個是 name,一個就是 arg:

當然得到的這個 name2,我還需要經過一個處理,爲什麼?

因爲這個 name2,都是 z- 開頭的。

其實 z- 這兩個字是沒必要的,因爲所有的指令都是 z- 開頭的,那麼我就只保留這個名字部分就行。

所以,我們可以跳過前兩個字:

至於剩下的 value,和剛纔一樣,也是 arrts[name]。

那麼這種情況下,我就給 directives 來 push 一個新東西:

當然,最後我們都處理完了,還得把這個 directives 給它返回出去:

順便一說,我個人比較喜歡把它的的結構放在外面。

這樣的話,以後看起來也會稍微的方便一些,其實就是個註釋:

然後我們來看看這個 _directives 到底對不對。

可以看到,是沒有問題的。

 

當然這時候,我們還得處理幾種特殊的情況。

首先第一種特殊的情況,就是 z-on,它也是一個指令,只不過它的功能,是用來搞 listener 的,那麼如果是這樣的話,我們是不是還得把這個 + 號也識別上。

第二,還有一種可能,我這有個指令,但是它沒有任何值,比如 z-aaa,這種其實是存在的:

一般來說,像這種指令,在 vue 裏面,它代表的是 true。

意思就是我加了這個,沒寫值,它默認就是一個 true。

所以這幾種,我們也稍微的來看看。

那麼,如果是 + 號開頭的,我需要幾個東西:

首先,我知道 +,它其實是 on 的簡稱。

所以我就去給 directives push 一下:

首先,name 就是 on,因爲它本來就是 on 的簡稱,我只是把它還原回來了而已。

接下來 arg,對於事件來說,它的意思就是具體的事件名,比如 mouseover。

以及 value,其實也是對應於 attrs[name]。

那麼我們來試試。

可以看到,都是 OK 的。

 

然後接下來,我們還要處理一種特殊的情況,比方說 z-aaa。

那麼首先,它能不能成爲我們這個指令的一員?毫無疑問是可以的,上圖中也有顯示。

但是它的 value 是一個空字符串。這其實是不對的,我希望它是 true。

因爲沒寫值,它默認就應該是個 true,這也是爲了我們其他的一些東西來考慮的。

 

那這時候有一個問題啊,我們怎麼區分這兩個東西:

z-aaa 是沒給,我們要算 true。

而 z-show="" 是給了,我們明確的表示,就是一個空字符串而已。

那這時候其實是應該要去區分它們倆的。

 

所以爲了能夠區分它倆,我們就先 console 出來看看:

那麼你可以明確的看到,在這裏,就已經分不清了。

因爲都是空字符串,那我咋區分啊?沒辦法,所以我們得往它上一層找。

這個 attrs 到我手裏,就已經分不清了,我們需要去看 createAttrs 裏面,到底是怎麼樣的。

首先,在循環裏面,我們把 attr 都打印出來看看:

那麼這時候,你可以明確的發現,它自動的給我加了一個等於空。

這並不是我加的,而是它加的。

然後我們用 getAttribute,來獲取這東西所對應的屬性值:

那麼這時候你可以明確的看到,它出來以後,就是這個空字符串。

所以現在的一個情況,就是我們想象當中的,想把 z-aaa 跟 z-show="" 分開,但是分的開嗎?

實際上來說,在 HTML 裏面,它就分不開,這是比較討厭的一件事。

那麼有沒有辦法分開?有,不過現階段,我們先不去管它,一步一步來。

那麼,我們現在需要做到的就是,獲取這些東西:

可以看到,是沒有任何問題的。

 

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