Accordion 折叠面板
单展开 / 多展开两种模式,3 种边框样式(bordered / flush / separated),可禁用单项。
基础用法
items 每项 { value, title, content?, disabled? }。默认 mode="single" —— 同时只能开一个,点击当前项会折叠它。
背景 视口
<script setup lang="ts">
import { CfAccordion } from '@chufix-design/vue';
const items = [
{
value: 'q1',
title: '础件能不能跟其他组件库共存?',
content: '可以。所有组件名带 Cf 前缀(CfButton / CfInput…),CSS 类名带 cf- 前缀,跟 Element / Ant / Naive 不会冲突。',
},
{
value: 'q2',
title: '需要 Vue 或 React 吗?',
content: '不需要。所有视觉走 CSS 类,纯 HTML + <link> 也能拿到 90% 的视觉。Modal / Tooltip / Toast 等带交互的需要少量 JS。',
},
{
value: 'q3',
title: '主题如何切换?',
content: '改 <html data-theme=""> 即可,三套主题:dark-cool(默认)/ dark-warm / light。',
},
];
</script>
<template>
<div style="width: 100%; max-width: 36rem;">
<CfAccordion :items="items" mode="single" variant="bordered" />
</div>
</template> <script setup>
import { CfAccordion } from '@chufix-design/vue';
const items = [
{
value: 'q1',
title: '础件能不能跟其他组件库共存?',
content: '可以。所有组件名带 Cf 前缀(CfButton / CfInput…),CSS 类名带 cf- 前缀,跟 Element / Ant / Naive 不会冲突。',
},
{
value: 'q2',
title: '需要 Vue 或 React 吗?',
content: '不需要。所有视觉走 CSS 类,纯 HTML + <link> 也能拿到 90% 的视觉。Modal / Tooltip / Toast 等带交互的需要少量 JS。',
},
{
value: 'q3',
title: '主题如何切换?',
content: '改 <html data-theme=""> 即可,三套主题:dark-cool(默认)/ dark-warm / light。',
},
];
</script>
<template>
<div style="width: 100%; max-width: 36rem;">
<CfAccordion :items="items" mode="single" variant="bordered" />
</div>
</template> import { CfAccordion } from '@chufix-design/react';
export default function Demo() {
const items = [
{ value: 'q1', title: '问题一', content: '答案一…' },
{ value: 'q2', title: '问题二', content: '答案二…' },
{ value: 'q3', title: '问题三', content: '答案三…' },
];
return (
<>
<CfAccordion items={items} mode="single" />
</>
);
} import { CfAccordion } from '@chufix-design/react';
export default function Demo() {
const items = [
{ value: 'q1', title: '问题一', content: '答案一…' },
{ value: 'q2', title: '问题二', content: '答案二…' },
{ value: 'q3', title: '问题三', content: '答案三…' },
];
return (
<>
<CfAccordion items={items} mode="single" />
</>
);
} 三种边框 variant
bordered—— 整体外框 + 项之间分隔线(默认)flush—— 没有外框,仅项间细线,融入页面背景separated—— 每项独立卡片 + 间距,块状层次更明显
背景 视口
<script setup lang="ts">
import { CfAccordion } from '@chufix-design/vue';
const items = [
{ value: 'a', title: '面板 A', content: '面板 A 的内容…' },
{ value: 'b', title: '面板 B', content: '面板 B 的内容…' },
{ value: 'c', title: '面板 C', content: '面板 C 的内容…' },
];
</script>
<template>
<div class="demo-stack" style="width: 100%; max-width: 36rem;">
<div>
<CfAccordion :items="items" variant="bordered" />
</div>
<div>
<CfAccordion :items="items" variant="flush" />
</div>
<div>
<CfAccordion :items="items" variant="separated" />
</div>
</div>
</template> <script setup>
import { CfAccordion } from '@chufix-design/vue';
const items = [
{ value: 'a', title: '面板 A', content: '面板 A 的内容…' },
{ value: 'b', title: '面板 B', content: '面板 B 的内容…' },
{ value: 'c', title: '面板 C', content: '面板 C 的内容…' },
];
</script>
<template>
<div class="demo-stack" style="width: 100%; max-width: 36rem;">
<div>
<CfAccordion :items="items" variant="bordered" />
</div>
<div>
<CfAccordion :items="items" variant="flush" />
</div>
<div>
<CfAccordion :items="items" variant="separated" />
</div>
</div>
</template> import { CfAccordion } from '@chufix-design/react';
export default function Demo() {
const items = [
{ value: 'a', title: '面板 A', content: '面板 A 的内容…' },
{ value: 'b', title: '面板 B', content: '面板 B 的内容…' },
{ value: 'c', title: '面板 C', content: '面板 C 的内容…' },
];
return (
<>
<CfAccordion items={items} variant="bordered" />
<CfAccordion items={items} variant="flush" />
<CfAccordion items={items} variant="separated" />
</>
);
} import { CfAccordion } from '@chufix-design/react';
export default function Demo() {
const items = [
{ value: 'a', title: '面板 A', content: '面板 A 的内容…' },
{ value: 'b', title: '面板 B', content: '面板 B 的内容…' },
{ value: 'c', title: '面板 C', content: '面板 C 的内容…' },
];
return (
<>
<CfAccordion items={items} variant="bordered" />
<CfAccordion items={items} variant="flush" />
<CfAccordion items={items} variant="separated" />
</>
);
} 多面板展开
mode="multiple" 让多个面板可以同时打开 —— 此时 modelValue / defaultOpen 是 string[]。常见于 FAQ 页或筛选侧栏。
背景 视口
一个双框架同源的基础组件库。
改 [data-theme] 三档主题切换。
<script setup lang="ts">
import { CfAccordion } from '@chufix-design/vue';
const items = [
{ value: 'q1', title: '什么是 ChuFix?', content: '一个双框架同源的基础组件库。' },
{ value: 'q2', title: '怎么安装?', content: 'pnpm i @chufix-design/vue 或 @chufix-design/react' },
{ value: 'q3', title: '设置主题?', content: '改 [data-theme] 三档主题切换。' },
];
</script>
<template>
<div style="width: 100%; max-width: 36rem;">
<CfAccordion
:items="items"
mode="multiple"
variant="separated"
:default-open="['q1', 'q3']"
/>
</div>
</template> <script setup>
import { CfAccordion } from '@chufix-design/vue';
const items = [
{ value: 'q1', title: '什么是 ChuFix?', content: '一个双框架同源的基础组件库。' },
{ value: 'q2', title: '怎么安装?', content: 'pnpm i @chufix-design/vue 或 @chufix-design/react' },
{ value: 'q3', title: '设置主题?', content: '改 [data-theme] 三档主题切换。' },
];
</script>
<template>
<div style="width: 100%; max-width: 36rem;">
<CfAccordion
:items="items"
mode="multiple"
variant="separated"
:default-open="['q1', 'q3']"
/>
</div>
</template> import { CfAccordion } from '@chufix-design/react';
export default function Demo() {
const items = [
{ value: 'q1', title: '什么是 ChuFix?', content: '一个双框架同源的基础组件库。' },
{ value: 'q2', title: '怎么安装?', content: 'pnpm i @chufix-design/vue 或 @chufix-design/react' },
{ value: 'q3', title: '设置主题?', content: '改 [data-theme] 三档主题切换。' },
];
return (
<>
<CfAccordion
items={items}
mode="multiple"
variant="separated"
defaultValue={['q1', 'q3']}
/>
</>
);
} import { CfAccordion } from '@chufix-design/react';
export default function Demo() {
const items = [
{ value: 'q1', title: '什么是 ChuFix?', content: '一个双框架同源的基础组件库。' },
{ value: 'q2', title: '怎么安装?', content: 'pnpm i @chufix-design/vue 或 @chufix-design/react' },
{ value: 'q3', title: '设置主题?', content: '改 [data-theme] 三档主题切换。' },
];
return (
<>
<CfAccordion
items={items}
mode="multiple"
variant="separated"
defaultValue={['q1', 'q3']}
/>
</>
);
} 禁用单项 + 默认展开
设 item.disabled = true 让单个面板不可点击。defaultOpen (Vue) / defaultValue (React) 控制初始展开。
背景 视口
正常展开 / 折叠。
<script setup lang="ts">
import { CfAccordion } from '@chufix-design/vue';
const items = [
{ value: 'a', title: '可点击的项', content: '正常展开 / 折叠。' },
{ value: 'b', title: '禁用项 — 点不动', content: '此项被锁定。', disabled: true },
{ value: 'c', title: '可点击的项', content: '正常展开 / 折叠。' },
];
</script>
<template>
<div style="width: 100%; max-width: 36rem;">
<CfAccordion :items="items" variant="bordered" :default-open="'a'" />
</div>
</template> <script setup>
import { CfAccordion } from '@chufix-design/vue';
const items = [
{ value: 'a', title: '可点击的项', content: '正常展开 / 折叠。' },
{ value: 'b', title: '禁用项 — 点不动', content: '此项被锁定。', disabled: true },
{ value: 'c', title: '可点击的项', content: '正常展开 / 折叠。' },
];
</script>
<template>
<div style="width: 100%; max-width: 36rem;">
<CfAccordion :items="items" variant="bordered" :default-open="'a'" />
</div>
</template> import { CfAccordion } from '@chufix-design/react';
export default function Demo() {
const items = [
{ value: 'a', title: '可点击的项', content: '正常展开 / 折叠。' },
{ value: 'b', title: '禁用项 — 点不动', content: '此项被锁定。', disabled: true },
{ value: 'c', title: '可点击的项', content: '正常展开 / 折叠。' },
];
return (
<>
<CfAccordion items={items} defaultValue="a" />
</>
);
} import { CfAccordion } from '@chufix-design/react';
export default function Demo() {
const items = [
{ value: 'a', title: '可点击的项', content: '正常展开 / 折叠。' },
{ value: 'b', title: '禁用项 — 点不动', content: '此项被锁定。', disabled: true },
{ value: 'c', title: '可点击的项', content: '正常展开 / 折叠。' },
];
return (
<>
<CfAccordion items={items} defaultValue="a" />
</>
);
} 自定义标题与面板内容 (具名插槽)
item.title / item.content 只能是字符串。需要在标题里加 tag、副标题、图标,或在面板内放表格、列表、表单等富内容时用动态具名插槽:
#title-${item.value}—— 自定义该项的标题#${item.value}—— 自定义该项的面板内容
只有提供了对应插槽的项才走自渲染,其他项继续按 item.title / item.content 渲染。
背景 视口
| 地区 | 时效 | 运费 |
|---|---|---|
| 本地 | 1–2 天 | 免 |
| 跨省 | 3–5 天 | 免 |
| 海外 | 10–15 天 | ¥80 |
<script setup lang="ts">
import { CfAccordion, CfTag } from '@chufix-design/vue';
const items = [
{ value: 'shipping', title: '运输方式' },
{ value: 'returns', title: '退换政策' },
{ value: 'beta', title: 'Beta 计划' },
];
</script>
<template>
<CfAccordion :items="items" variant="separated" :default-open="'shipping'">
<!-- 自定义标题:加 tag / 副标题 -->
<template #title-shipping>
<span class="adm-title">
运输方式
<CfTag size="sm" tone="success" variant="soft">免运费</CfTag>
</span>
</template>
<template #title-returns>
<span class="adm-title">
退换政策
<span class="adm-sub">30 天无理由</span>
</span>
</template>
<template #title-beta>
<span class="adm-title">
Beta 计划
<CfTag size="sm" tone="warning" variant="soft">实验性</CfTag>
</span>
</template>
<!-- 自定义面板内容:表格、列表等富内容 -->
<template #shipping>
<table class="adm-tab">
<tr><th>地区</th><th>时效</th><th>运费</th></tr>
<tr><td>本地</td><td>1–2 天</td><td>免</td></tr>
<tr><td>跨省</td><td>3–5 天</td><td>免</td></tr>
<tr><td>海外</td><td>10–15 天</td><td>¥80</td></tr>
</table>
</template>
<template #returns>
<ul class="adm-list">
<li>购买后 30 天内可申请退换</li>
<li>商品需保持全新且配件齐全</li>
<li>非质量问题往返运费由买家承担</li>
</ul>
</template>
<template #beta>
<p class="adm-p">
加入 Beta 计划后可优先体验新功能 —— 包括<strong>每周构建</strong>、
实验性 API、未完成的 UI 等。请勿在生产环境使用。
</p>
</template>
</CfAccordion>
</template>
<style scoped>
.adm-title { display: inline-flex; align-items: center; gap: 8px; }
.adm-sub { color: var(--fg-3); font-size: var(--t-12); }
.adm-tab { border-collapse: collapse; width: 100%; font-size: var(--t-13); }
.adm-tab th, .adm-tab td { border: 1px solid var(--line-1); padding: 6px 10px; text-align: left; }
.adm-tab th { background: var(--bg-2); color: var(--fg-2); font-weight: 600; }
.adm-list { margin: 0; padding-left: 18px; color: var(--fg-2); line-height: 1.7; }
.adm-p { margin: 0; color: var(--fg-2); line-height: 1.6; }
</style> <script setup>
import { CfAccordion, CfTag } from '@chufix-design/vue';
const items = [
{ value: 'shipping', title: '运输方式' },
{ value: 'returns', title: '退换政策' },
{ value: 'beta', title: 'Beta 计划' },
];
</script>
<template>
<CfAccordion :items="items" variant="separated" :default-open="'shipping'">
<!-- 自定义标题:加 tag / 副标题 -->
<template #title-shipping>
<span class="adm-title">
运输方式
<CfTag size="sm" tone="success" variant="soft">免运费</CfTag>
</span>
</template>
<template #title-returns>
<span class="adm-title">
退换政策
<span class="adm-sub">30 天无理由</span>
</span>
</template>
<template #title-beta>
<span class="adm-title">
Beta 计划
<CfTag size="sm" tone="warning" variant="soft">实验性</CfTag>
</span>
</template>
<!-- 自定义面板内容:表格、列表等富内容 -->
<template #shipping>
<table class="adm-tab">
<tr><th>地区</th><th>时效</th><th>运费</th></tr>
<tr><td>本地</td><td>1–2 天</td><td>免</td></tr>
<tr><td>跨省</td><td>3–5 天</td><td>免</td></tr>
<tr><td>海外</td><td>10–15 天</td><td>¥80</td></tr>
</table>
</template>
<template #returns>
<ul class="adm-list">
<li>购买后 30 天内可申请退换</li>
<li>商品需保持全新且配件齐全</li>
<li>非质量问题往返运费由买家承担</li>
</ul>
</template>
<template #beta>
<p class="adm-p">
加入 Beta 计划后可优先体验新功能 —— 包括<strong>每周构建</strong>、
实验性 API、未完成的 UI 等。请勿在生产环境使用。
</p>
</template>
</CfAccordion>
</template>
<style scoped>
.adm-title { display: inline-flex; align-items: center; gap: 8px; }
.adm-sub { color: var(--fg-3); font-size: var(--t-12); }
.adm-tab { border-collapse: collapse; width: 100%; font-size: var(--t-13); }
.adm-tab th, .adm-tab td { border: 1px solid var(--line-1); padding: 6px 10px; text-align: left; }
.adm-tab th { background: var(--bg-2); color: var(--fg-2); font-weight: 600; }
.adm-list { margin: 0; padding-left: 18px; color: var(--fg-2); line-height: 1.7; }
.adm-p { margin: 0; color: var(--fg-2); line-height: 1.6; }
</style> import { CfAccordion, CfTag } from '@chufix-design/react';
export default function Demo() {
const items = [
{ value: 'shipping', title: '运输方式' },
{ value: 'returns', title: '退换政策' },
{ value: 'beta', title: 'Beta 计划' },
];
return (
<>
<CfAccordion items={items} variant="separated" defaultOpen={'shipping'}>
<span className="adm-title">
运输方式
<CfTag size="sm" tone="success" variant="soft">免运费</CfTag>
</span>
</>
);
} import { CfAccordion, CfTag } from '@chufix-design/react';
export default function Demo() {
const items = [
{ value: 'shipping', title: '运输方式' },
{ value: 'returns', title: '退换政策' },
{ value: 'beta', title: 'Beta 计划' },
];
return (
<>
<CfAccordion items={items} variant="separated" defaultOpen={'shipping'}>
<span className="adm-title">
运输方式
<CfTag size="sm" tone="success" variant="soft">免运费</CfTag>
</span>
</>
);
} API
Props
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
items | Array<{ value, title, content?, disabled? }> | [] | 面板列表 |
mode | 'single' | 'multiple' | 'single' | 同时只能开一个 / 可多开 |
variant | 'bordered' | 'flush' | 'separated' | 'bordered' | 边框样式 |
modelValue (Vue) / value (React) | string | string[] | — | 受控当前展开 |
defaultOpen (Vue) / defaultValue (React) | string | string[] | — | 非受控初始展开 |
mode="single"时受控 / 非受控值是string;mode="multiple"时是string[]。
Events
| Vue 事件 | React 回调 | 载荷类型 | 说明 |
|---|---|---|---|
update:modelValue | onChange | string | string[] | 展开状态变化时触发;single 模式是 string,multiple 模式是 string[] |
Slots (Vue)
| Slot 名 | 说明 |
|---|---|
title-${item.value} | 动态具名 —— 自定义指定项的标题 |
${item.value} | 动态具名 —— 自定义指定项的面板内容 |
反馈与讨论
Accordion 折叠面板 的讨论