4. 插槽
插槽允许父组件为消费方(consumer)插入的内容预留占位。
具名插槽
父组件(Card.sharq):
xml
<template>
<ui:VisualElement $MainElement class="card">
<slot name="header" />
<ui:VisualElement class="card__body">
<slot /> <!-- default — slot without name -->
</ui:VisualElement>
<slot name="footer" />
</ui:VisualElement>
</template>消费方:
xml
<sus:Card>
<!-- v-slot:header → falls into <slot name="header"> -->
<template v-slot:header>
<ui:Label text="Card Header" style="font-size: 18px;" />
</template>
<!-- Without v-slot → falls into <slot /> (default) -->
<ui:Label text="Main content goes here" />
<!-- v-slot:footer → hits <slot name="footer"> -->
<template v-slot:footer>
<sus:SusButton text="OK" />
</template>
</sus:Card>SlotPropMap
csharp
public class SlotPropMap : Dictionary<string, object>
{
// Passes data from the parent slot to the consumer
}工作原理
编译器会在父组件中生成:
csharp
var __slot_header = GetSlotContainer("header");
this.Add(__slot_header);
BuildSlot("header", null, __slot_header);
var __slot_default = GetSlotContainer("default");
this.Add(__slot_default);
BuildSlot("default", null, __slot_default);在消费方中:
csharp
RegisterSlotContent("header", __el, null);为插槽容器设置样式
GetSlotContainer() 返回一个真实的 VisualElement,它位于模板中包裹 <slot> 的元素内部。 它带有两个固定的 USS 类:
sus-slot— 每个插槽容器都有;sus-slot--<name>— 例如sus-slot--header、sus-slot--default。
容器本身不附带任何布局(UI Toolkit 默认值:flex-direction: column)。因此设置为行方向的 外层元素只会影响这一个盒子本身——被投影的子元素仍然会垂直排列。需要在容器上重复设置方向:
css
.my-card__actions { flex-direction: row; align-items: center; }
.my-card__actions > .sus-slot { flex-direction: row; align-items: center; }不要依赖类型选择器(> VisualElement)来实现这一点——真正的约定是这个类。