Accordion 折叠列表

多段内容依次展开与收起的折叠列表。

登录后进入创作者中心,选择作品类型并填写资料,提交后进入审核队列。

<script setup lang="ts">
  import {
    Accordion,
    AccordionContent,
    AccordionItem,
    AccordionTrigger,
    Card,
    Text,
  } from '@hina-ui/vue'
</script>

<template>
  <Card class="w-full max-w-md">
    <Accordion default-value="submit">
      <AccordionItem value="submit">
        <AccordionTrigger>如何投稿</AccordionTrigger>
        <AccordionContent>
          <Text tone="muted" size="sm">
            登录后进入创作者中心,选择作品类型并填写资料,提交后进入审核队列。
          </Text>
        </AccordionContent>
      </AccordionItem>
      <AccordionItem value="review">
        <AccordionTrigger>审核需要多久</AccordionTrigger>
        <AccordionContent>
          <Text tone="muted" size="sm">通常在三个工作日内完成,资料不全时会退回补充。</Text>
        </AccordionContent>
      </AccordionItem>
      <AccordionItem value="edit">
        <AccordionTrigger>可以修改已发布的内容吗</AccordionTrigger>
        <AccordionContent>
          <Text tone="muted" size="sm">可以。修改会生成新的版本,经审核后替换当前内容。</Text>
        </AccordionContent>
      </AccordionItem>
    </Accordion>
  </Card>
</template>
vue

用法

import { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from '@hina-ui/vue'
ts

组件由四部分构成:Accordion 持有展开状态,AccordionItem 是一段内容,AccordionTrigger 是该段的标题与切换控件,AccordionContent 是被折叠的正文。每一段以 value 标识。

默认一次只展开一段,点击另一段时当前段收起。触发器自带随开合旋转的指示物。

<script setup lang="ts">
  import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Text } from '@hina-ui/vue'
</script>

<template>
  <Accordion class="w-full max-w-md">
    <AccordionItem value="intro">
      <AccordionTrigger>作品简介</AccordionTrigger>
      <AccordionContent>
        <Text tone="muted" size="sm">转学第一天,我在天台遇见了那个抱着旧相机的少女。</Text>
      </AccordionContent>
    </AccordionItem>
    <AccordionItem value="staff">
      <AccordionTrigger>制作人员</AccordionTrigger>
      <AccordionContent>
        <Text tone="muted" size="sm">原作、脚本与原画均由同一位作者完成。</Text>
      </AccordionContent>
    </AccordionItem>
  </Accordion>
</template>
vue

只有一处内容需要折叠时使用 Collapsible。

示例

允许全部收起

默认展开的一段不能再次点击收起。设置 collapsible 后可以收起当前段,列表可以处于全部收起的状态。defaultValue 指定初始展开的段。

转学第一天,我在天台遇见了那个抱着旧相机的少女。

<script setup lang="ts">
  import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Text } from '@hina-ui/vue'
</script>

<template>
  <Accordion collapsible default-value="intro" class="w-full max-w-md">
    <AccordionItem value="intro">
      <AccordionTrigger>作品简介</AccordionTrigger>
      <AccordionContent>
        <Text tone="muted" size="sm">转学第一天,我在天台遇见了那个抱着旧相机的少女。</Text>
      </AccordionContent>
    </AccordionItem>
    <AccordionItem value="staff">
      <AccordionTrigger>制作人员</AccordionTrigger>
      <AccordionContent>
        <Text tone="muted" size="sm">原作、脚本与原画均由同一位作者完成。</Text>
      </AccordionContent>
    </AccordionItem>
  </Accordion>
</template>
vue

多段同时展开

type 设为 multiple 后各段独立开合,v-model 与 defaultValue 的值为数组。

转学第一天,我在天台遇见了那个抱着旧相机的少女。

原作、脚本与原画均由同一位作者完成。

<script setup lang="ts">
  import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Text } from '@hina-ui/vue'
</script>

<template>
  <Accordion type="multiple" :default-value="['intro', 'staff']" class="w-full max-w-md">
    <AccordionItem value="intro">
      <AccordionTrigger>作品简介</AccordionTrigger>
      <AccordionContent>
        <Text tone="muted" size="sm">转学第一天,我在天台遇见了那个抱着旧相机的少女。</Text>
      </AccordionContent>
    </AccordionItem>
    <AccordionItem value="staff">
      <AccordionTrigger>制作人员</AccordionTrigger>
      <AccordionContent>
        <Text tone="muted" size="sm">原作、脚本与原画均由同一位作者完成。</Text>
      </AccordionContent>
    </AccordionItem>
    <AccordionItem value="release">
      <AccordionTrigger>发售信息</AccordionTrigger>
      <AccordionContent>
        <Text tone="muted" size="sm">2024 年冬季发售,支持简体中文。</Text>
      </AccordionContent>
    </AccordionItem>
  </Accordion>
</template>
vue

受控

v-model 将展开状态交由外部持有,页面上的其他控件也可以切换展开的段。

转学第一天,我在天台遇见了那个抱着旧相机的少女。

<script setup lang="ts">
  import { ref } from 'vue'
  import {
    Accordion,
    AccordionContent,
    AccordionItem,
    AccordionTrigger,
    Button,
    Inline,
    Stack,
    Text,
  } from '@hina-ui/vue'

  const open = ref('intro')
</script>

<template>
  <Stack class="w-full max-w-md">
    <Inline>
      <Button size="sm" variant="soft" tone="neutral" @click="open = 'intro'">看简介</Button>
      <Button size="sm" variant="soft" tone="neutral" @click="open = 'staff'">看制作人员</Button>
    </Inline>
    <Accordion v-model="open">
      <AccordionItem value="intro">
        <AccordionTrigger>作品简介</AccordionTrigger>
        <AccordionContent>
          <Text tone="muted" size="sm">转学第一天,我在天台遇见了那个抱着旧相机的少女。</Text>
        </AccordionContent>
      </AccordionItem>
      <AccordionItem value="staff">
        <AccordionTrigger>制作人员</AccordionTrigger>
        <AccordionContent>
          <Text tone="muted" size="sm">原作、脚本与原画均由同一位作者完成。</Text>
        </AccordionContent>
      </AccordionItem>
    </Accordion>
  </Stack>
</template>
vue

禁用

AccordionItem 的 disabled 禁用单段,Accordion 的 disabled 禁用整组。

转学第一天,我在天台遇见了那个抱着旧相机的少女。

<script setup lang="ts">
  import {
    Accordion,
    AccordionContent,
    AccordionItem,
    AccordionTrigger,
    Stack,
    Text,
  } from '@hina-ui/vue'
</script>

<template>
  <Stack gap="lg" class="w-full max-w-md">
    <Accordion default-value="intro">
      <AccordionItem value="intro">
        <AccordionTrigger>作品简介</AccordionTrigger>
        <AccordionContent>
          <Text tone="muted" size="sm">转学第一天,我在天台遇见了那个抱着旧相机的少女。</Text>
        </AccordionContent>
      </AccordionItem>
      <AccordionItem value="staff" disabled>
        <AccordionTrigger>制作人员</AccordionTrigger>
        <AccordionContent>
          <Text tone="muted" size="sm">原作、脚本与原画均由同一位作者完成。</Text>
        </AccordionContent>
      </AccordionItem>
    </Accordion>
    <Accordion disabled>
      <AccordionItem value="intro">
        <AccordionTrigger>作品简介</AccordionTrigger>
        <AccordionContent>
          <Text tone="muted" size="sm">转学第一天,我在天台遇见了那个抱着旧相机的少女。</Text>
        </AccordionContent>
      </AccordionItem>
      <AccordionItem value="staff">
        <AccordionTrigger>制作人员</AccordionTrigger>
        <AccordionContent>
          <Text tone="muted" size="sm">原作、脚本与原画均由同一位作者完成。</Text>
        </AccordionContent>
      </AccordionItem>
    </Accordion>
  </Stack>
</template>
vue

标题层级

触发器渲染在标题元素内,默认为 h3。level 可以改为其他层级,以符合页面的标题结构。

常见问题

<script setup lang="ts">
  import {
    Accordion,
    AccordionContent,
    AccordionItem,
    AccordionTrigger,
    Heading,
    Stack,
    Text,
  } from '@hina-ui/vue'
</script>

<template>
  <Stack class="w-full max-w-md">
    <Heading :level="3" size="md">常见问题</Heading>
    <Accordion>
      <AccordionItem value="submit">
        <AccordionTrigger :level="4">如何投稿</AccordionTrigger>
        <AccordionContent>
          <Text tone="muted" size="sm">登录后进入创作者中心,选择作品类型并填写资料。</Text>
        </AccordionContent>
      </AccordionItem>
      <AccordionItem value="review">
        <AccordionTrigger :level="4">审核需要多久</AccordionTrigger>
        <AccordionContent>
          <Text tone="muted" size="sm">通常在三个工作日内完成。</Text>
        </AccordionContent>
      </AccordionItem>
    </Accordion>
  </Stack>
</template>
vue

更换指示物

icon 插槽仅替换指示物的字形,旋转仍由组件负责;将 icon 设为 false 则不显示指示物。

<script setup lang="ts">
  import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Text } from '@hina-ui/vue'
  import { Plus } from '@lucide/vue'
</script>

<template>
  <Accordion class="w-full max-w-md">
    <AccordionItem value="intro">
      <AccordionTrigger>
        作品简介
        <template #icon><Plus /></template>
      </AccordionTrigger>
      <AccordionContent>
        <Text tone="muted" size="sm">转学第一天,我在天台遇见了那个抱着旧相机的少女。</Text>
      </AccordionContent>
    </AccordionItem>
    <AccordionItem value="staff">
      <AccordionTrigger :icon="false">制作人员</AccordionTrigger>
      <AccordionContent>
        <Text tone="muted" size="sm">原作、脚本与原画均由同一位作者完成。</Text>
      </AccordionContent>
    </AccordionItem>
  </Accordion>
</template>
vue

行为

  • 展开与收起时内容区的高度随之变化,两个方向使用同一组过渡参数。
  • 收起时内容从无障碍树中移除,键盘焦点不会进入其中。
  • 各段之间以细线分隔。组件本身没有底色与边框,需要卡片外观时放入 Card。

无障碍

  • 触发器是标题中的按钮,带 aria-expanded 与 aria-controls。
  • 上下方向键在触发器之间移动焦点,Home 与 End 跳到首尾。
  • 内容区带 region 角色,屏幕阅读器按区域朗读。

API

Accordion

属性
类型
默认值
说明
type
'single' | 'multiple'
'single'
一次展开一段或者多段
collapsible
boolean
false
single 模式下是否允许全部收起
modelValue
string | string[]
—
展开的段,支持 v-model
defaultValue
string | string[]
—
初始展开的段
disabled
boolean
false
是否禁用整组
class
string
—
追加至根元素的类名
事件
参数
说明
update:modelValue
value: string | string[]
展开的段变化

AccordionItem

属性
类型
默认值
说明
value
string
—
该段的标识,必填
disabled
boolean
false
是否禁用该段
class
string
—
追加至该段的类名

AccordionTrigger

属性
类型
默认值
说明
level
2 | 3 | 4 | 5 | 6
3
标题层级
icon
boolean
true
是否显示展开指示物
class
string
—
追加至触发器的类名
插槽
说明
default
触发器的文字
icon
替换指示物的字形

AccordionContent

属性
类型
默认值
说明
class
string
—
追加至内容区的类名