跳到主要內容
+

覆寫元件結構

了解如何覆寫 Joy UI 元件的預設 DOM 結構。

Joy UI 元件的設計旨在適用於最廣泛的使用情境,但您偶爾可能需要變更元件結構在 DOM 中的呈現方式。

為了理解如何做到這一點,擁有元件的準確心智模型會很有幫助。

心智模型

元件的結構由填充該元件「插槽 (slots)」的元素決定。插槽最常由 HTML 標籤填充,但也可能由 React 元件填充。

所有元件都包含一個「根插槽 (root slot)」,用於定義它們在 DOM 樹中的主要節點;更複雜的元件還包含以它們所代表的元素命名的額外「內部插槽 (interior slots)」。

所有非公用程式 (non-utility) 的 Joy UI 元件都接受兩個 props 來覆寫它們的呈現 HTML 結構

  • component—覆寫根插槽
  • slots—取代任何內部插槽(如果存在)以及根插槽

此外,您可以使用 slotProps 將自訂 props 傳遞到內部插槽。

根插槽

根插槽代表元件的最外層元素。它由具有適當 HTML 元素的樣式化元件 (styled component) 填充。

例如,「按鈕 (Button)」的根插槽是一個 <button> 元素。此元件有一個根插槽;更複雜的元件可能會有額外的內部插槽

component prop

使用 component prop 來覆寫元件的根插槽。下面的示範展示了如何將「按鈕 (Button)」的 <button> 標籤替換為 <a> 以建立連結按鈕

按下 Enter 鍵開始編輯

內部插槽

複雜的元件由一個或多個內部插槽以及根插槽組成。這些插槽通常(但不一定)巢狀於根插槽內。

例如,「自動完成 (Autocomplete)」由一個根 <div> 組成,其中包含多個以它們所代表的元素命名的內部插槽:input、startDecorator、endDecorator、clearIndicator、popupIndicator 等等。

slots prop

使用 slots prop 來取代元件的內部插槽。下面的範例展示了如何取代「自動完成 (Autocomplete)」元件中的 listbox 插槽以移除彈出視窗功能

按下 Enter 鍵開始編輯

slotProps prop

slotProps prop 是一個物件,其中包含元件內所有插槽的 props。您可以使用它來定義額外的自訂 props 以傳遞到元件的內部插槽。

例如,下面的程式碼片段展示了如何將自訂 data-testid 新增到「自動完成 (Autocomplete)」元件的 listbox 插槽

<Autocomplete slotProps={{ listbox: { 'data-testid': 'my-listbox' } }} />

放置在主要元件上的所有額外 props 也會傳播到根插槽(就像它們被放置在 slotProps.root 中一樣)。這兩個範例是等效的

<Autocomplete id="badge1">
<Autocomplete slotProps={{ root: { id: 'badge1' } }}>

最佳實務

使用 componentslotProps.{slot}.component prop 來覆寫元素,同時保留插槽的樣式。

使用 slots prop 來使用您的自訂元件取代插槽的樣式和功能。

使用 component 覆寫可讓您將該元素的屬性直接套用到根插槽。例如,如果您使用 <li> 標籤覆寫「按鈕 (Button)」的根插槽,您可以將 <li> 屬性 value 直接新增到元件。如果您對 slots.root 執行相同的操作,則需要將此屬性放在 slotProps.root 物件上,以避免 TypeScript 錯誤。

當覆寫更複雜元件的插槽時,請注意您呈現的 DOM 結構。如果您過度偏離預設結構,您可能會輕易破壞語意化 (semantic) 和可存取 HTML 的規則 — 例如,不小心將區塊層級 (block-level) 元素巢狀於行內 (inline) 元素內。Joy UI 元件會自動修正語意上不正確的 HTML — 詳細資訊請參閱〈自動調整 (Automatic adjustment)〉。