应使用 uni-accordion 替代已废弃的 uni-collapse,它语义清晰、跨端兼容、api 稳定;安装最新版后导入注册,通过 list 传数据、active 控制展开项;异步加载需配合 body-style 或 $nexttick 调用 init;样式应通过 head-style/body-style 内联控制;app 端建议关闭 show-animation 避免卡顿。

直接用 uni-accordion,别碰已废弃的 uni-collapse —— 官方 2023 年起就移除了它,硬写会报错:Component is not found in path "uni_modules/uni-collapse/components/uni-collapse/uni-collapse"。
用 uni-accordion 替代是最稳路径
它就是官方为替代 uni-collapse 而保留并持续维护的手风琴组件,语义、交互、跨端兼容性(H5 / 微信小程序 / App)全对齐,且 API 清晰。
- 先装最新版:
npm install @dcloudio/uni-ui@latest - 在页面
<script></script>中 import:import uniAccordion from '@dcloudio/uni-ui/lib/uni-accordion/uni-accordion.vue' - 注册进
components选项,再按数组格式传数据:list = [{ title: 'Q1', content: 'A1' }, { title: 'Q2', content: 'A2' }] - 控制展开项用
active:单选传Number(如0),多选传Array<number></number>(如[0, 2])
动态加载内容后高度塌陷或留白?别只靠 init()
从接口拉完数据再渲染到 uni-accordion-item 里,常出现展开后内容被截断、底部大片空白 —— 组件初始化时缓存了空 DOM 的高度,异步数据回来后没重算。
-
init()方法在部分版本(尤其旧版@dcloudio/uni-ui)中不可靠:调了也不触发重绘,或仅对首次生效 - 更稳妥的做法是:给内容区加
:body-style="{ minHeight: 'auto' }",或直接用max-height+transition自控动画(绕过组件内部高度逻辑) - 若必须用
init(),确保在$nextTick后调用,且数据已赋值完成
样式改不动?别碰 .u-collapse-item__header 这类 class
直接写 scoped 样式覆盖内部 class,极易因组件升级或平台差异失效。官方明确推荐通过内联 props 控制样式。
- 标题栏统一用
:head-style,比如::head-style="{ padding: '16rpx 20rpx', backgroundColor: '#f9f9f9' } - 内容区用
:body-style,比如::body-style="{ padding: '12rpx 20rpx', borderTop: '1rpx solid #eee' } - 图标替换走
slot="title",里面塞<u-icon></u-icon>或自定义<image></image>,别动源码 - 避免
!important—— 后续换暗色模式或主题时会变成硬伤
App 端动画卡顿?关掉 show-animation 是正解
不是你代码写得不好,是低端 Android 原生渲染层对 CSS height 过渡支持极差,容易掉帧甚至白屏。官方文档也明确建议 App 端默认关闭。
- 全局加
:show-animation="false",H5 和小程序可保留动画 - 别迷信“有动画才专业”——用户感知到的响应速度和稳定性,远比视觉过渡重要
- 如果真要保动画,H5 下可用
transform: scaleY()替代height,但小程序不支持该方案
真正难的从来不是“怎么让内容收起来”,而是异步内容加载后高度重算的时机、多端动画兼容性取舍、以及样式入口是否稳定 —— 这些细节不处理好,FAQ 页面上线后就会在某个机型上突然错位或卡死。











