1. 程式人生 > 實用技巧 >2020.11.6 自己實現小紅點提示(後來才發現元件庫裡有233

2020.11.6 自己實現小紅點提示(後來才發現元件庫裡有233

今天要做一個功能:當面試官推送給考生一道題時,考生側邊欄中的“題目”標籤頁上要有相關提醒。

我是第一次實現這個功能,首先我需要知道“小紅點”是怎麼做出來的。

小紅點可以用CSS畫出來:

<div class="point"></div>

然後想,紅點應該放在哪裡。我是這樣想的,雖然紅點是在“題目“右上角,但是不應該放在”題目“標籤頁中。如果是放在裡面,那不點開這個,是看不到紅點的。

所以我先考慮把紅點放在了Tabs中,與兩個TabPanel並排,效果有了,推送題目的時候紅點也會出現,檢視後也會消失。但是,我這裡的佈局發生了變化:

可以看到,有紅點時,聊天和題目都往右挪了一些位置,我不希望它們發生變化。所以再次思考小紅點的位置。

然後我突然想到,這個紅點,肯定不能放在”題目“的TabPanel中,那能不能放在”聊天“的TabPanel中呢?因為紅點的隱藏與顯示的邏輯,是在整個函式元件中判斷的,所以其實放在哪個標籤中,都不會影響它的邏輯。而且反正看了題目小紅點就會消去,所以放在”聊天“中應該是可以的。

最後我就是這麼做的,需要說一下的是小紅點是怎麼放在題目上面的。我使用的是絕對定位,top:45px; right:260px,這樣在全屏的情況下,小紅點就落在了題目右上角。但是這樣其實是不對的,position:absolute是相對上一個被position定位的元素,因此此時小紅點是相對整個視窗定位,隨著視窗變化,小紅點也亂動。所以我把側邊欄設定為position:relative

,這樣就穩定了。加深了我對position的理解。

然後是小紅點根據推送題目與否,顯示與隱藏的邏輯。這個我花了很長時間,先是思考通過什麼來判斷收到了題目推送,然後是根據推送,怎麼設計邏輯。

我找到了考生處顯示題目的元件,理解了元件的功能後,其中的n=problems.length,就是統計題目的長度,每推送過來一個題目,都會存在problems中,然後通過取problems[n-1],來獲得最新一道題的資訊並展示。所以我就想通過判斷n是否比上一個n大,來決定是否推送了新題目。

(還需要說,我也找到了傳送題目的程式碼,但是我認為,傳送題目與接收題目還有一個網路傳輸過程,通過接收題目與否來判斷,更加合理)

當有新題目推送過來的時候,不是所有情況都需要顯示紅點的,當我們在”聊天“標籤頁時,還沒有看到題目,需要顯示小紅點;當我們在”題目“標籤頁時,頁面可以響應式地展示新推送過來的題目,就不需要展示小紅點了。

題目->聊天:不需要展示紅點,而且在下一道題推送過來之前,都不展示紅點。

聊天->題目:展示紅點,切換到”題目“標籤頁時,紅點消失,而且在下一道題推送過來之前,都不展示紅點。

已讀的題目,重新整理或者斷線重連後都還是已讀狀態;同理,未讀的題目,也一直是未讀狀態。

基本的邏輯已經梳理完了,還有一些實現細節。

首先是一個useStatemodel集合,如果推送了新的題目,就通過setHasNewhasNew設定為true(初始狀態設定為false)。

通過TabsOnChange回撥方法,該方法會將當前TabPanelkey作為返回引數。我們可以利用它來幫助我們判斷當前是從”聊天“切到”題目“,還是從”題目“切到”聊天“。為了實現這個判斷,我們需要再設定一個const [keyNum, setKeyNum] = useState("0"),我們用它表示切換前的TabPanel.


然後是展示的邏輯,如果有新題目,且我們不在”題目“標籤頁,那就展示,否則隱藏。

重新整理的情況還沒完成,因為一重新整理,n就重新賦值了,會經歷從初始值開始的賦值,而這時會錯誤地將題目設定為未讀。等週三看看吳老師怎麼弄。

可以使用sessionStorage來儲存。