代码演示
如何引入
<script setup lang="ts">
import { Collapse } from '@fibrous/semi-ui-vue';
</script>
Collapse.Panel 也可以按名导入:CollapsePanel。Panel 的 header、extra 是插槽(#header、#extra)。Panel 只能在 Collapse 内使用,否则抛出说明性错误。
基本用法
可以同时展开多个面板,可以通过 defaultActiveKey 设置默认展开的面板。
代码
<script setup lang="ts">
import { Collapse } from '@fibrous/semi-ui-vue';
</script>
<template>
<Collapse>
<Collapse.Panel itemKey="1">
<template #header>This is panel header 1</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
<Collapse.Panel itemKey="2">
<template #header>This is panel header 2</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
<Collapse.Panel itemKey="3">
<template #header>This is panel header 3</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
</Collapse>
</template>手风琴效果
可以通过设置 accordion 使每次只允许展开一个面板。
代码
<script setup lang="ts">
import { Collapse } from '@fibrous/semi-ui-vue';
</script>
<template>
<Collapse accordion>
<Collapse.Panel itemKey="1">
<template #header>This is panel header 1</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
<Collapse.Panel itemKey="2">
<template #header>This is panel header 2</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
<Collapse.Panel itemKey="3">
<template #header>This is panel header 3</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
</Collapse>
</template>禁用面板
可以通过设置 disabled 禁用面板。
代码
<script setup lang="ts">
import { Collapse } from '@fibrous/semi-ui-vue';
</script>
<template>
<Collapse accordion>
<Collapse.Panel disabled itemKey="1">
<template #header>This is panel header 1</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
<Collapse.Panel itemKey="2">
<template #header>This is panel header 2</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
<Collapse.Panel itemKey="3">
<template #header>This is panel header 3</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
</Collapse>
</template>隐藏面板展开/收起图标
可以通过设置 showArrow 隐藏面板展开/收起图标。
代码
<script setup lang="ts">
import { Collapse } from '@fibrous/semi-ui-vue';
</script>
<template>
<Collapse accordion>
<Collapse.Panel itemKey="1" :showArrow="false">
<template #header>This is panel header 1</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
<Collapse.Panel itemKey="2">
<template #header>This is panel header 2</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
<Collapse.Panel itemKey="3">
<template #header>This is panel header 3</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
</Collapse>
</template>自定义展开图标
可以通过 Collapse 的 #expandIcon 插槽设置展开图标,#collapseIcon 插槽设置折叠图标。插槽存在但内容为空表示不显示图标。已知限制:使用方用 v-if 整体增删这两个插槽时,面板可能停在旧图标。
展开图标在面板收起时显示(表示可以展开),折叠图标在面板展开时显示。
代码
<script setup lang="ts">
import { IconMinus, IconPlus } from '@fibrous/semi-icons-vue';
import { Collapse } from '@fibrous/semi-ui-vue';
</script>
<template>
<Collapse>
<template #expandIcon>
<IconPlus />
</template>
<template #collapseIcon>
<IconMinus />
</template>
<Collapse.Panel itemKey="1">
<template #header>This is panel header 1</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
<Collapse.Panel itemKey="2">
<template #header>This is panel header 2</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
<Collapse.Panel itemKey="3">
<template #header>This is panel header 3</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
</Collapse>
</template>自定义右上角辅助区域内容
通过 #extra 插槽设置右上角辅助区域内容。
#header 渲染在面板的切换按钮内,只能放文字、图标等非交互内容;#extra 位于同一行、按钮之外,可以放按钮、输入框等控件。
代码
<script setup lang="ts">
import { IconCopy } from '@fibrous/semi-icons-vue';
import { Collapse, Tag } from '@fibrous/semi-ui-vue';
</script>
<template>
<Collapse>
<Collapse.Panel itemKey="1">
<template #header>This is panel header 1</template>
<template #extra>1234</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
<Collapse.Panel itemKey="2">
<template #header>This is panel header 2</template>
<template #extra>
<IconCopy />
</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
<Collapse.Panel itemKey="3">
<template #header>This is panel header 3</template>
<template #extra>
<Tag color="violet" :style="{ margin: 0 }">Recommended</Tag>
</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
</Collapse>
</template>API 参考
Collapse
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| activeKey | 受控属性,当前展开面板的 key;null 与空字符串表示全部收起。 | string | string[] | null | undefined |
| defaultActiveKey | 初始展开面板的 key。 | string | string[] | semiDefault("Collapse", "defaultActiveKey", "") |
| accordion | 手风琴模式。 | boolean | semiGlobalDefault("Collapse", "accordion") |
| clickHeaderToExpand | 点击面板头整行展开收起;为 false 时只响应切换按钮和箭头。 | boolean | semiDefault("Collapse", "clickHeaderToExpand", true) |
| expandIconPosition | 展开图标位置,可选 left、right。 | "left" | "right" | semiDefault("Collapse", "expandIconPosition", "right") |
| keepDOM | 是否保留隐藏面板的 DOM 树,默认销毁;未传时依次读 Collapse、Collapsible 的全局默认值。 | boolean | semiGlobalDefault("Collapse", "keepDOM") |
| motion | 是否开启动画,默认开启;未传时依次读 Collapse、Collapsible 的全局默认值。 | boolean | semiGlobalDefault("Collapse", "motion") |
| lazyRender | 配合 keepDOM 使用,为 true 时面板展开前不渲染内容。 | boolean | semiDefault("Collapse", "lazyRender", false) |
Events
| 事件 | 说明 | 回调参数 |
|---|---|---|
| update:activeKey | 展开面板变化时触发,参数总是 string[],配合 v-model:activeKey 使用。 | [activeKey: string[]] |
| change | 切换面板时触发,参数为展开面板的 key 数组与原生 MouseEvent(键盘操作经原生按钮同样是 click)。 | [activeKey: string[], event: MouseEvent] |
Slots
| 插槽 | 说明 | 作用域参数 |
|---|---|---|
| default | Collapse.Panel 面板。 | any |
| expandIcon | 面板收起时显示的图标,默认 IconChevronDown;插槽内容为空则不显示图标。 | any |
| collapseIcon | 面板展开时显示的图标,默认 IconChevronUp;插槽内容为空则不显示图标。 | any |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| 无 |
class、style 与原生属性经 attrs 传入,落在 Collapse 根元素上。update:activeKey 与 change 的 activeKey 总是 string[]:v-model:activeKey 的初值为字符串时,第一次变更后变为数组。
Collapse.Panel
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| itemKey | 必填且唯一,用于匹配 activeKey 与 defaultActiveKey。 | string | undefined |
| showArrow | 是否展示箭头。 | boolean | true |
| disabled | 面板是否被禁用。 | boolean | false |
Events
| 事件 | 说明 | 回调参数 |
|---|---|---|
| motionEnd | 展开或收起动画结束时触发。 | [] |
Slots
| 插槽 | 说明 | 作用域参数 |
|---|---|---|
| default | 面板内容。 | any |
| header | 面板头内容,渲染在切换按钮内,不能包含交互元素。 | any |
| extra | 面板头右侧的辅助内容,位于切换按钮之外,可以放控件。 | any |
Exposes
| 名称 | 说明 | 类型 |
|---|---|---|
| 无 |
class、style 与原生属性经 attrs 传入,落在 Panel 根元素(.semi-collapse-item)上。Panel 不读全局默认值。
Accessibility
ARIA
- 面板头遵循 WAI-ARIA Accordion 模式:原生
button外包role="heading"、aria-level="3"的元素,按钮的可访问名称是header内容。 - 按钮带
aria-expanded;面板内容仍在 DOM 中时一律带指向它的aria-controls:展开时总在;收起时内容在 DOM 中的情况包括keepDOM生效(含只在 Collapsible 的全局默认值里设置keepDOM)且内容已经渲染过,例如keepDOM加lazyRender下展开过一次再收起;lazyRender尚未渲染的收起面板没有内容,不带aria-controls。 - 面板内容是
role="region",通过aria-labelledby以按钮为名称;keepDOM保留的收起内容设置inert。 - 展开图标是装饰,设置
aria-hidden="true";extra位于按钮之外。 disabled面板使用按钮的原生disabled属性。
键盘和焦点
- 每个面板头按钮是一个 Tab 停靠点,禁用面板被跳过。
- 焦点在按钮上时按
Enter或Space展开或收起面板,clickHeaderToExpand为false时同样有效。 extra中的控件是各自的 Tab 停靠点。
文案规范
折叠面板本质是卡片容器增加了收起和展开的功能,所以折叠面板的文案规范需要和 卡片文案规范 保持一致
设计变量
| Sass 变量 | 值 | 用法 |
|---|---|---|
| $color-collapse_item-border-default | var(--semi-color-border) | 分割线颜色 |
| $color-collapse_header-text-default | var(--semi-color-text-0) | 标题文字颜色 |
| $color-collapse_header-text-disabled | var(--semi-color-disabled-text) | 标题文字颜色 禁用 |
| $color-collapse_header-icon-default | var(--semi-color-text-2) | 展开箭头图标颜色 |
| $color-collapse_header-bg-hover | var(--semi-color-fill-0) | 菜单项背景颜色 - 悬浮 |
| $color-collapse_header-bg-active | var(--semi-color-fill-1) | 菜单项背景颜色 - 按下 |
| $color-collapse_content-text-default | var(--semi-color-text-1) | 内容文字颜色 |
| $font-collapse_header-fontWeight | $font-weight-bold | 标题字重 |
| $spacing-collapse_header-marginX | $spacing-tight | 标题水平外边距 |
| $spacing-collapse_header-marginY | $spacing-extra-tight | 标题垂直外边距 |
| $spacing-collapse_header-padding | $spacing-tight | 标题内边距 |
| $spacing-collapse_right-paddingRight | $spacing-tight | 图标右侧内边距 |
| $spacing-collapse_header_iconLeft-marginRight | 8px | |
| $spacing-collapse_content-paddingTop | $spacing-extra-tight | 内容顶部内边距 |
| $spacing-collapse_content-paddingRight | $spacing-base | 内容右侧内边距 |
| $spacing-collapse_content-paddingBottom | $spacing-tight | 内容底部内边距 |
| $spacing-collapse_content-paddingLeft | $spacing-base | 内容左侧内边距 |
| $radius-collapse_header | var(--semi-border-radius-small) | 内容圆角大小 |
| $width-collapse_item-border | 1px | 分割线宽度 |
| $size-collapse_icon-default | $width-icon-medium | 图标尺寸 |
FAQ
-
Collapse 内嵌表单收起后表单数据会清空 ?
Collapse 收起之后,默认会销毁相应的 DOM 。所以相应的 field 被卸载了,数据也被清空。可以将 Collapse 的
keepDOM设为 true,保留对应的 DOM 节点。 -
面板头整行是折叠、展开的点击热区,在这一行放置控件(例如 Input)后,点击它会导致 Collapse 收起/展开。如何避免?
控件放在
extra而不是header中:header位于切换按钮内,不能包含控件。设置clickHeaderToExpand为false时只有切换按钮和箭头响应点击;否则在控件的点击回调中阻止事件冒泡至面板头即可,若控件未提供 event 对象,在外层包裹元素的点击回调中阻止冒泡亦可,见下方示例。
<script setup lang="ts">
import { Collapse, Input } from '@fibrous/semi-ui-vue';
</script>
<template>
<Collapse>
<Collapse.Panel itemKey="1">
<template #header>Panel header</template>
<template #extra>
<span @click.stop>
<Input aria-label="面板备注" />
</span>
</template>
<p>Hi, bytedance dance dance. This is the docsite of Semi UI.</p>
</Collapse.Panel>
</Collapse>
</template>