Collapsible 折叠面板

展开或折叠内容的容器

何时使用

  • 需要展开或收起内容、节省空间时。

导入

import {
  Collapsible,
  CollapsibleRoot,
  CollapsibleTrigger,
  CollapsibleContent,
} from "@reglow/reui";

支持两种使用方式:配置式Collapsible 自定义动画)和复合式CollapsibleRoot + CollapsibleTrigger + CollapsibleContent,基于 reka-ui 无障碍支持)。

基础用法

通过 isOpen 控制内容的展开或折叠。

<script setup>
import { ref } from "vue";
import { Collapsible } from "@reglow/reui";

const isOpen = ref(false);
</script>

<template>
  <div>
    <button @click="isOpen = !isOpen">Toggle</button>
    <Collapsible :is-open="isOpen">
      <ul>
        <li><p>Semi Design 以内容优先进行设计。</p></li>
        <li><p>更容易地自定义主题。</p></li>
        <li><p>适用国际化场景。</p></li>
        <li><p>效率场景加入人性化关怀</p></li>
      </ul>
    </Collapsible>
  </div>
</template>

复合式(CollapsibleRoot)

基于 reka-ui 无头组件,内置 ARIA 无障碍支持和键盘导航,通过 CSS 动画控制展开/折叠。

<script setup>
import { CollapsibleRoot, CollapsibleTrigger, CollapsibleContent } from "@reglow/reui";
import { ChevronDown } from "lucide-vue-next";
</script>

<template>
  <CollapsibleRoot>
    <CollapsibleTrigger as-child>
      <button class="flex items-center gap-2">
        <span>展开/折叠</span>
        <ChevronDown class="size-4 transition-transform duration-200 group-data-[state=open]:rotate-180" />
      </button>
    </CollapsibleTrigger>
    <CollapsibleContent class="data-[state=open]:animate-[collapsible-down_200ms_ease-out] data-[state=closed]:animate-[collapsible-up_200ms_ease-out] overflow-hidden">
      <div class="pt-2">
        <p>通过 CSS 动画控制展开/折叠</p>
      </div>
    </CollapsibleContent>
  </CollapsibleRoot>
</template>

自定义动画时间

通过 duration 设置动画时间(毫秒)。

<script setup>
import { ref } from "vue";
import { Collapsible } from "@reglow/reui";

const isOpen = ref(false);
const duration = ref(500);
</script>

<template>
  <button @click="isOpen = !isOpen">Toggle</button>
  <Collapsible :is-open="isOpen" :duration="duration">
    <p>动画时间 500ms</p>
  </Collapsible>
</template>

关闭动画

通过 motionfalse 关闭动画。

<template>
  <Collapsible :is-open="isOpen" :motion="false">
    <p>无动画折叠</p>
  </Collapsible>
</template>

自定义折叠高度

通过 collapseHeight 设置收起时的高度。

<script setup>
import { ref } from "vue";
import { Collapsible } from "@reglow/reui";

const isOpen = ref(false);
</script>

<template>
  <button @click="isOpen = !isOpen">Toggle</button>
  <Collapsible :is-open="isOpen" :collapse-height="80">
    <div style="mask-image: linear-gradient(to bottom, black 0%, rgba(0,0,0,1) 60%, rgba(0,0,0,0.2) 80%, transparent 100%);">
      <p>Semi Design 以内容优先进行设计。</p>
      <p>更容易地自定义主题。</p>
      <p>适用国际化场景。</p>
      <p>效率场景加入人性化关怀</p>
    </div>
  </Collapsible>
</template>

淡入淡出

通过 fade 开启内容淡入淡出效果。

<template>
  <Collapsible :is-open="isOpen" fade>
    <p>淡入淡出动画</p>
  </Collapsible>
</template>

嵌套使用

<script setup>
import { ref } from "vue";
import { Collapsible } from "@reglow/reui";

const isOpen = ref(false);
const isChildOpen = ref(false);
</script>

<template>
  <div>
    <button @click="isOpen = !isOpen">Toggle 外层</button>
    <Collapsible :is-open="isOpen">
      <div>
        <p>外层内容</p>
        <button @click="isChildOpen = !isChildOpen">Toggle 内层</button>
        <Collapsible :is-open="isChildOpen">
          <p>内层内容</p>
        </Collapsible>
      </div>
    </Collapsible>
  </div>
</template>

保留 DOM 与延迟渲染

通过 keepDOM 保留隐藏的 DOM 树(默认销毁)。配合 lazyRendertrue 时挂载时不渲染。

<template>
  <Collapsible :is-open="isOpen" keep-dom lazy-render>
    <p>首次展开时才渲染</p>
  </Collapsible>
</template>

重新计算高度

通过 reCalcKey 在内容变化时重新计算高度。

<script setup>
import { ref } from "vue";
import { Collapsible } from "@reglow/reui";

const isOpen = ref(true);
const itemCount = ref(3);
const reCalcKey = ref(0);

const addItem = () => {
  itemCount.value++;
  reCalcKey.value++;
};
</script>

<template>
  <button @click="isOpen = !isOpen">Toggle</button>
  <button @click="addItem">添加项</button>
  <Collapsible :is-open="isOpen" :re-calc-key="reCalcKey">
    <ul>
      <li v-for="i in itemCount" :key="i">项目 {{ i }}</li>
    </ul>
  </Collapsible>
</template>

API

Collapsible Props(配置式)

参数说明类型默认值
isOpen是否展开booleanfalse
duration动画时间(毫秒)number250
motion是否开启动画booleantrue
collapseHeight折叠高度number0
collapseHeightAdaptive内容高度小于 collapseHeight 时自适应booleanfalse
fade是否开启淡入淡出booleanfalse
keepDOM是否保留隐藏的 DOMbooleanfalse
lazyRender配合 keepDOM,挂载时不渲染booleanfalse
reCalcKey改变时重新计算高度string | number-
id元素 idstring-
class附加类名string-
style附加样式CSSProperties-

Collapsible Events

事件说明回调参数
motionEnd动画结束回调()

Collapsible Slots

名称说明
default折叠内容

CollapsibleRoot Props(复合式)

基于 reka-ui CollapsibleRoot,接受以下 props:

参数说明类型默认值
defaultOpen默认是否展开booleanfalse
open受控展开状态(v-model)boolean-
disabled是否禁用booleanfalse
dir方向ltr | rtlltr

CollapsibleRoot Events

事件说明回调参数
update:open展开状态变化(open: boolean)

CollapsibleRoot Slots

名称说明参数
default内容{ state: open | closed }

CollapsibleTrigger Props(复合式)

参数说明类型默认值
asChild是否将 props 合并到子元素booleanfalse
as渲染的元素string | Componentbutton

CollapsibleContent Props(复合式)

参数说明类型默认值
forceMount是否强制挂载booleanfalse
asChild是否将 props 合并到子元素booleanfalse
as渲染的元素string | Componentdiv

两种模式对比

维度Collapsible(配置式)CollapsibleRoot(复合式)
动画JS 高度动画CSS 动画(data-state)
无障碍需手动配置 ARIAreka-ui 内置 ARIA + 键盘导航
功能丰富(duration/fade/collapseHeight/lazyRender 等)基础(open/close)
适用场景需要精细控制动画需要无障碍 + 简单折叠