Skip to content

SplitButton 分裂按钮 ​

分裂按钮把「当前操作」和「同类操作的其它选择」放在同一个胶囊里:左半段是普通的按钮,右半段带下拉箭头, 点开一个 Menu。它由 SplitButton、Menu 与 MenuItem 组合,菜单项写在默认插槽里。

基础用法 ​

主操作:—;菜单选择:—

vue
<script setup lang="ts">
import { SplitButton, MenuItem } from "@sharpdotnut/dotsharp";
import saveIcon from "@iconify-icons/material-symbols/save";
</script>

<template>
  <SplitButton label="保存" :icon="saveIcon" menu-label="更多保存方式">
    <MenuItem label="另存为" value="另存为" />
    <MenuItem label="保存副本" value="保存副本" />
    <MenuItem label="导出为 PDF" value="导出为 PDF" />
  </SplitButton>
</template>
  • @click 只来自左半段(右半段会阻止冒泡),@select 携带被点菜单项的 value。
  • 两段共享容器:底色、文字色、边框与阴影都画在根元素上,中间那条分隔线用 currentColor 的 30% 透明度, 所以明暗主题与所有层级都自动适配。

层级 ​

variant 与 Button 完全一致:elevated、filled(默认)、tonal、outlined、text。

vue
<script setup lang="ts">
import { ref } from "vue";
import { SplitButton, MenuItem } from "@sharpdotnut/dotsharp";
import editIcon from "@iconify-icons/material-symbols/edit";

const outlined = ref("—");
</script>

<template>
  <SplitButton label="编辑" :icon="editIcon" menu-label="更多编辑操作" variant="filled">
    <MenuItem label="重命名" value="重命名" />
  </SplitButton>
  <SplitButton
    label="编辑"
    :icon="editIcon"
    menu-label="更多编辑操作"
    variant="outlined"
    @select="outlined = String($event)"
  >
    <MenuItem label="重命名" value="重命名" />
    <MenuItem label="移动到…" value="移动到…" />
  </SplitButton>
  <SplitButton label="编辑" :icon="editIcon" menu-label="更多编辑操作" variant="text">
    <MenuItem label="重命名" value="重命名" />
  </SplitButton>
</template>

尺寸与禁用 ​

size 与 Button 一致(sm / md / lg)。disabled 同时禁用两段;menuDisabled 只禁用尾部分段, 主操作仍然可用。

vue
<SplitButton label="保存" size="sm" menu-label="更多保存方式">
  <MenuItem label="另存为" value="另存为" />
</SplitButton>
<SplitButton label="保存" menu-label="更多保存方式" menu-disabled>
  <MenuItem label="另存为" value="另存为" />
</SplitButton>
<SplitButton label="保存" menu-label="更多保存方式" disabled>
  <MenuItem label="另存为" value="另存为" />
</SplitButton>

菜单方向 ​

placement 默认 bottom-end:菜单的右边缘与按钮的右边缘对齐。其它取值与 Menu 相同 (bottom-start),菜单空间不足时会自动翻到上方。

vue
<SplitButton label="保存" menu-label="更多保存方式" placement="bottom-start">
  <MenuItem label="另存为" value="另存为" />
</SplitButton>

API ​

SplitButton ​

属性类型默认值说明
labelstring—主按钮文本
iconIconifyIcon | string—主按钮前置图标
menuLabelstring—尾部分段的无障碍名称,必填
variant"elevated" | "filled" | "tonal" | "outlined" | "text""filled"视觉层级
size"sm" | "md" | "lg""md"高度 32 / 40 / 48px
placement"bottom-start" | "bottom-end" | "right-start""bottom-end"菜单相对尾部分段的展开方向
disabledbooleanfalse两段都禁用
menuDisabledbooleanfalse只禁用尾部分段
type"button" | "submit" | "reset""button"主按钮的原生类型
事件载荷说明
selectstring | number菜单项被选中时的标识值
  • 默认插槽:菜单内容,通常是若干 MenuItem。
  • 根元素是 div,其余属性与事件透传到该元素;class 落在容器上。
  • 尾部分段带 aria-haspopup="menu" 与 aria-expanded,↓ 键可直接展开菜单;Esc 收起并把焦点交还尾部。

可访问性 ​

两段都是原生 button,因此各自可 Tab 到达;焦点样式是内侧 2px 的 outline-ds-focus,不会被胶囊边界裁掉。 尾部按钮通过 aria-label(menuLabel)得到名称——它只有图标,没有可见文字。