「組件」設計一款Notice組件

image

前言

最近在使用Vue+TypeScript鼓搗本身的組件庫,期間參考很多(抄😂)elementiview的源碼。發現了一些經常使用的功能的背後,每每是複雜的實現。因而準備寫一系列文章,介紹這些組件背後的原理。今天是第一篇,手把手帶你實現Notice組件。css

API設計

一般咱們在使用iview或者element的Notice組件的時候,都是經過調用掛載到Vue原型鏈上的方法的形式。以下圖所示。react

image

咱們的組件的調用方式,也參考相似的設計, 不一樣的是咱們新添加了一個APIsetLen。代碼以下git

這是由於樓主曾經接過一個需求,在作公司一款toC的時候,產品不但願屏幕上出現太多的通知框,而是但願一次最多隻出現3個。全部樓主在設計組件的時候,將這個定製化的需求也添加了上去。github

image

由於咱們須要實現,屏幕上只顯示指定數量的Notice通知框,因此咱們使用兩個數組,保存Notice的實例。queue隊列用來存儲所有的Notice實例,showQueue用來屏幕上顯示的Notice實例。數組

$Notice,方法用來想queue添加了一個Notice的實例; processQueue方法則用來處理queue隊列; remove方法刪除特定的Notice; clear方法則用來清除所有的Notice。setLen用來設定同屏顯示Notice的數量。len屬性則是同屏的最大數量。app

模版設計

模版設計沒啥好說的,常規佈局。其中Icon組件,是我以前寫的圖標組件。showClose,控制是否顯示Icon圖標。visible控制Notice的顯隱。iview

image

方法設計

$Notice

image

使用Vue.extend方法構建NoticeConstructor,NoticeConstructor是Vue的子類。NoticeConstructor的實例,能夠使用mount方法生成DOM,而後手動或者指定mount的參數,將DOM渲染到頁面之中。函數

在Notice方法的內部,使用uuid, 生成一個惟一id,這個惟一的標記,將會幫助咱們查找隊列中指定的notice對象。緊接着咱們會對onClose方法進行一層包裝。onClose將會在每次關閉notice的時候調用,onClose在內部調用Notice.remove方法,Notice.remove方法會將指定的id所對應的notice對象移除出隊列佈局

接着咱們將建立notice的實例,並將其push到queue隊列中,接着調用$Notice.processQueue方法處理queue隊列。學習

關於uuid這個方法,uuid這個方法生成的並非真的惟一id,而是一個重複機率很低的id。重複機率大概是1ms內,1億多分之1吧。這個是我在stackoverflow上找的方法,代碼以下。

image

$Notice.processQueue

image

在processQueue方法中,咱們首先判斷showQueue隊列是否是滿的。若是不是,咱們將會從queue隊列的頭部截取一個notice對象。使用$mount方法,生成DOM並append到body中。

由於notice在頁面上的樣式,是自上而下的,因此咱們將會計算notice的相對頂部的偏移量,每個notice對象的自身高度和15px的間距。

同時,咱們會將notice的visible屬性設置爲true,這會觸發咱們的transition動畫,並將這個notice對象push到showQueue隊列中。

生命週期 mounted

image

接着咱們將目光轉移到Notice組件內部,咱們將notice,append到DOM中後。咱們會在mounted函數中起一個定時器,定時器將會等待指定的duration毫秒,duration是咱們指定notice存在的時間,若是duration爲0,notice將會永遠存在。

duration毫秒以後,將會執行notice組件內部的close方法。

close

image

在close方法中,咱們會爲當前組件添加transitionend,事件。這個事件將會在css動畫(離場動畫)結束後觸發。咱們將visible設置爲false這會觸發,組件的離場動畫。接着咱們調用onClose方法,這會處理咱們的隊列。

$Notice.remove

以前咱們對onClose進行了一層包裝,調用onClose方法,會調用咱們的$Notice.remove方法。

image

在$Notice.remove方法中,咱們將會經過id找到須要移除的notice對象,將其移除出showQueue隊列。

接着循環剩下的showQueue隊列,將它們style.top向上移動。最後咱們繼續調用$Notice.processQueue方法,從queue隊列中,拉取新的notice對象,push到showQueue隊列中。

destroy

當離場動畫執行完畢後,transitionend回調會調用destroy方法。

image

destroy將會主動卸載咱們的組件,並從DOM中移除咱們的元素。notice對象的生命週期至此結束。

$Notice.clear

$Notice.setLen

clear和setLen相對而言比較簡單,這裏就再也不贅述了。

image

後續

  1. 「組件」設計一款Input組件
  2. 「組件」設計一款Grid組件
  3. 「組件」設計一款Button組件
  4. 「組件」設計一款Collapse組件
  5. 「組件」設計一款Icon組件
  6. 「組件」設計一款Select組件
  7. 「組件」設計一款Autocomplete組件 .....

本系列的文章,儘可能作到短小精悍。Select,Table,DatePicker組件將會難點。

明天可能會更新一篇React Hook的學習文章。由於報名了週末晚上的公開課介紹Hook的原理。下週想從新閱讀下preact的源碼,學習學習preact中hook的實現原理。

參考

相關文章
相關標籤/搜索