在小程序开发中,日程列表通常会包含大量条目,如果默认全部展开,不仅占用过多屏幕空间,还会让用户难以快速定位重点内容。通过一键展开和收缩功能,可以让界面在简洁与详尽之间自由切换。核心思路是利用页面的 data 状态控制渲染逻辑,再配合视图层的样式或条件指令完成交互。

数据状态与结构设计
实现展开和收缩的第一步,是在页面的 data 中声明一个控制状态的字段,例如 isExpand,其值为布尔类型。与此同时,日程数据通常以数组形式存在,如 scheduleList,每个元素包含时间、标题与详情。将状态与数据分离,可以让视图层仅依赖 isExpand 决定显示条数或高度,而不必修改原始数据。
为了提升可维护性,建议把“默认展示条数”也写入 data,例如 defaultCount: 3。当 isExpand 为 false 时,列表只渲染前三项;为 true 时渲染全部。这样的结构在后续扩展筛选、分组等功能时,不会破坏展开收缩的基础逻辑。下方代码展示了基础的 data 定义:
Page({
data: {
isExpand: false,
defaultCount: 3,
scheduleList: [
{ time: '09:00', title: '晨会', detail: '同步当日目标' },
{ time: '11:00', title: '客户沟通', detail: '确认需求文档' },
{ time: '14:00', title: '代码评审', detail: '检查合并请求' },
{ time: '16:00', title: '周报撰写', detail: '整理进度数据' },
{ time: '18:00', title: '健身', detail: '有氧训练三十分钟' }
]
}
});
上述结构中,scheduleList 不受展开状态影响,视图层通过计算得到“当前应渲染的列表”。这种单向数据流降低了调试难度,也方便在 onLoad 时从接口获取真实日程后直接赋值。
视图层条件渲染与事件绑定
在 wxml 中,可以通过 wx:if 结合表达式控制列表渲染范围。一种常见写法是使用计算属性般的写法,在 wxml 里直接利用 isExpand 判断:未展开时取 scheduleList.slice(0, defaultCount),展开时取原数组。由于小程序不支持在模板中直接调用方法,我们通常在 js 里用 setData 维护一个 showList 字段。
按钮的事件处理函数非常简洁,只需对 isExpand 取反,并重新计算 showList。使用 bindtap 绑定到按钮上,用户点击即触发状态切换。注意不要使用 wx:if 和 hidden 混用在同一节点上,否则会造成逻辑冲突。以下代码演示了事件处理与列表更新:
toggleExpand: function () {
const isExpand = !this.data.isExpand;
const list = isExpand
? this.data.scheduleList
: this.data.scheduleList.slice(0, this.data.defaultCount);
this.setData({
isExpand: isExpand,
showList: list
});
}
对应的 wxml 结构如下,按钮文字根据状态动态变化,列表渲染 showList 即可。这样无论数据量多大,渲染节点数都受控,不会因一次性画出几十条而卡顿。
<view class="schedule">
<block wx:for="{{showList}}" wx:key="time">
<view class="item">
<text>{{item.time}} {{item.title}}</text>
<text class="detail">{{item.detail}}</text>
</view>
</block>
<button bindtap="toggleExpand">
{{isExpand ? '收起' : '展开全部'}}
</button>
</view>
如果希望未展开时保留容器高度平滑变化,也可以不切换数组,而是给外层容器动态加 class,用 CSS 的 max-height 配合 overflow 实现。但这种方式在条目极多时仍会渲染全部节点,仅适合数据量较小的场景。
动画与体验优化
生硬的高度变化会让用户感觉突兀。小程序提供了 wx.createAnimation 接口,可以在展开和收缩时加入过渡。思路是在 toggle 函数中创建动画对象,根据 isExpand 设定目标高度,然后导出动画数据绑定到视图。
另一种轻量方案是使用 CSS transition。给列表容器设定 transition: max-height 0.3s ease;,通过 class 切换改变 max-height 值。相比 JS 动画,CSS 方案性能更好且代码更少。需要注意的是,max-height 不能设为 auto,必须给一个足够大的固定值,否则过渡无效。下面给出一个 CSS 配合 class 的示例:
.schedule-list {
max-height: 180rpx;
overflow: hidden;
transition: max-height 0.3s ease;
}
.schedule-list.expanded {
max-height: 1200rpx;
}
在 wxml 中,根据 isExpand 给容器加上 expanded 类即可。若日程可能超过 1200rpx,可按条数估算后动态设置行内样式。最终用户点击按钮,列表平滑展开,再次点击平滑收起,交互清晰且不干扰页面其他模块。这种实现兼顾了性能与体验,也易于移植到其它列表型小程序页面中。