You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在accordion折叠面板中保持至少一个expansion panel始终展开?

实现思路

核心逻辑是记录当前展开的面板ID/索引,在用户触发展开/关闭操作时校验:如果当前操作是要关闭最后一个处于展开状态的面板,直接拦截该操作即可。

不同场景的实现示例

1. 原生JavaScript + HTML 实现

  • 先给每个面板加自定义属性比如data-panel-id,用变量expandedPanels存储当前展开的面板ID集合
  • 给每个面板的头部加点击事件监听:
// 初始化默认展开第一个面板
let expandedPanels = new Set(['panel1'])

document.querySelectorAll('.expansion-panel-header').forEach(header => {
  header.addEventListener('click', (e) => {
    const targetPanelId = e.currentTarget.parentElement.dataset.panelId
    const isCurrentExpanded = expandedPanels.has(targetPanelId)
    
    // 如果是要关闭当前唯一展开的面板,直接拦截
    if (isCurrentExpanded && expandedPanels.size === 1) {
      return
    }
    
    // 正常切换展开/关闭状态
    if (isCurrentExpanded) {
      expandedPanels.delete(targetPanelId)
      e.currentTarget.parentElement.classList.remove('expanded')
    } else {
      // 如果是手风琴模式(一次只展开一个),先清空集合再添加
      // expandedPanels.clear()
      expandedPanels.add(targetPanelId)
      e.currentTarget.parentElement.classList.add('expanded')
    }
  })
})

2. Vue3 + Element Plus 实现

如果用Element Plus的el-collapse组件,直接利用before-close钩子拦截即可:

<template>
  <el-collapse v-model="activeName" :before-close="handleBeforeClose">
    <el-collapse-item title="面板1" name="1"></el-collapse-item>
    <el-collapse-item title="面板2" name="2"></el-collapse-item>
    <el-collapse-item title="面板3" name="3"></el-collapse-item>
  </el-collapse>
</template>
<script setup>
import { ref } from 'vue'
// 初始化默认展开第一个面板
const activeName = ref(['1'])

const handleBeforeClose = (closingName) => {
  // 如果当前要关闭的是唯一展开的面板,返回false阻止关闭
  if (activeName.value.length === 1 && activeName.value[0] === closingName) {
    return false
  }
  return true
}
</script>

3. React + Ant Design 实现

用Ant Design的Collapse组件,监听onChange事件,判断变更后的展开列表是否为空,为空就保持之前的展开状态:

import { useState } from 'react'
import { Collapse } from 'antd'

const items = [
  { key: '1', label: '面板1', children: '内容1' },
  { key: '2', label: '面板2', children: '内容2' },
  { key: '3', label: '面板3', children: '内容3' },
]

export default function App() {
  const [activeKey, setActiveKey] = useState(['1'])

  const handleChange = (newActiveKey) => {
    // 如果新的展开列表为空,不更新状态
    if (newActiveKey.length === 0) return
    setActiveKey(newActiveKey)
  }

  return <Collapse activeKey={activeKey} onChange={handleChange} items={items} />
}
注意事项
  • 初始化的时候一定要默认展开至少一个面板,避免初始状态就全关
  • 如果是手风琴模式(一次只能展开一个),逻辑可以更简化:禁止点击当前已经展开的面板的关闭操作即可

内容的提问来源于stack exchange,提问作者code

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 01:18:02