承上篇,核心的 Tabs 其實已經建立好了,當內容不能呈現出來就不算真正的完成!因此本篇來看看要如何顯示對應的資料。
簡短回顧一下我們的 state 長什麼樣子:
{
currentTab: null, //目前瀏覽Tab的id
storedTabs: [...], //存放的Tab的id們
}
通常 Tabs 元件會依照實際的項目數量搭配對應的 Panels,也就是說有幾個分頁,就會有幾組頁面要顯示:
上圖擷取 MUI 的範例,一個Tab對應一個Panel。
不過由於我們的Panel都是呈現訂單,既然如此只需要一個 Panel ,再把 id 傳入,讓 OrderPanel 可以透過 id 去打API抓取資料回來顯示:
<Tabs>
{/* 忽略 */}
</Tabs>
<OrderPanel key={tabs.currentTab} orderId={tabs.currentTab} />
其中 Key 是比較關鍵的地方,實作細節不一,(可能)會遇到資料顯示不正確,這時候可以運用 Key 的機制來重新渲染整個元件。
依照情境,你也可以傳入整包訂單的資料。
實際上 <OrderPanel />
裡面就單純只是資料的排版與顯示,很純!(就不範例了)
其實非常簡單,基本的功能這樣就完成了,簡單展示一次:
但這樣就完成好像太...水了!
常常瀏覽網站或是VSC要關閉時,會用到全部關閉或是關閉其他分頁的功能,
老闆:「這看起來很實用,不然就加一加吧!」
我: (內心: (/゚Д゚)/你以為想加就加)
接下來就是:
可以使用 onContextMenu 搭配 Menu + PopOver 等方式製作,製作方式請容許先略過,簡單來說就是點右鍵開啟選單,留意的是這邊記得 event.preventDefault()
不然還是會看到原本的選單。
而只需要把對應的事件傳入即可:
<OrderTab
{...忽略其他}
onClose={() => tabDispatch("REMOVE", tab.id)} //重複使用的關閉
onCloseAll={() => tabDispatch("RESET")} //關閉全部
onCloseOthers={() => tabDispatch("ONLY", tab.id)} //關閉其他
/>
在 useTabs 中的 reducer 新增兩種方式:
case "RESET": {
return initValue
}
case "ONLY": {
const only = state.storedTabs.find((tab) => tab.id === payload)
return {
currentTab: payload,
storedTabs: only ? [only] : [],
}
}
RESET
關閉全部,單純就是回歸到最初的狀態ONLY
關閉其他,則是藉由傳入的id
,找到後並保留下來最後就是...完成啦!
可以延伸功能,像是 drag and drop(拖曳) 來移動位置,或是實務上遇到複雜的內容,可以再搭配 Context Provider 把 useTabs 包裝進去傳遞給跨界 子民? 子元件來使用。