覆盖组件结构
了解如何覆盖 Joy UI 组件的默认 DOM 结构。
Joy UI 组件旨在适应最广泛的用例,但您有时可能需要更改组件结构在 DOM 中的呈现方式。
为了理解如何做到这一点,拥有组件的准确心智模型会有所帮助。
心智模型
组件的结构由填充该组件**插槽**的元素决定。插槽最常由 HTML 标签填充,但也可能由 React 组件填充。
所有组件都包含一个**根插槽**,用于定义它们在 DOM 树中的主要节点;更复杂的组件还包含以它们所代表的元素命名的其他**内部插槽**。
所有非实用程序 Joy UI 组件都接受两个属性来覆盖其渲染的 HTML 结构
component
——覆盖根插槽slots
——替换任何内部插槽(如果存在)以及根插槽
此外,您可以使用 slotProps
将自定义属性传递给内部插槽。
根插槽
根插槽代表组件的最外层元素。它由一个带有适当 HTML 元素的样式化组件填充。
例如,Button 的根插槽是一个 <button>
元素。此组件仅有一个根插槽;更复杂的组件可能有额外的内部插槽。
component
属性
使用 component
属性来覆盖组件的根插槽。下面的演示展示了如何将 Button 的 <button>
标签替换为 <a>
以创建一个链接按钮
内部插槽
复杂组件由一个或多个内部插槽以及根插槽组成。这些插槽通常(但不一定)嵌套在根插槽内。
例如,Autocomplete 由一个根 <div>
组成,该根 <div>
包含多个以它们所代表的元素命名的内部插槽:input、startDecorator、endDecorator、clearIndicator、popupIndicator 等等。
slots
属性
使用 slots
属性来替换组件的内部插槽。下面的示例展示了如何替换 Autocomplete 组件中的 listbox 插槽以删除弹出功能
slotProps
属性
`slotProps` 属性是一个对象,其中包含组件内所有插槽的属性。您可以使用它来定义要传递给组件内部插槽的其他自定义属性。
例如,下面的代码片段展示了如何向 Autocomplete 组件的 listbox 插槽添加自定义 data-testid
<Autocomplete slotProps={{ listbox: { 'data-testid': 'my-listbox' } }} />
放置在主组件上的所有其他属性也会传播到根插槽中(就像它们放置在 slotProps.root 中一样)。这两个示例是等效的
<Autocomplete id="badge1">
<Autocomplete slotProps={{ root: { id: 'badge1' } }}>
最佳实践
使用 component
或 slotProps.{slot}.component
属性通过保留插槽的样式来覆盖元素。
使用 slots
属性将插槽的样式和功能替换为您自定义的组件。
使用 component
进行覆盖允许您将该元素的属性直接应用于根元素。例如,如果您使用 <li>
标签覆盖 Button 的根元素,则可以直接将 <li>
属性 value
添加到组件。如果您对 slots.root
执行相同的操作,则需要将此属性放在 slotProps.root
对象上,以避免 TypeScript 错误。
在覆盖更复杂组件的插槽时,请注意您渲染的 DOM 结构。如果您偏离默认结构太远,很容易破坏语义化和可访问 HTML 的规则——例如,无意中将块级元素嵌套在内联元素中。Joy UI 组件会自动纠正语义上不正确的 HTML——有关详细信息,请参阅自动调整。