环境
小程序环境:
-
微信开发者工具:RC 1.06.2503281 win32-x64
-
基础运行库:3.8.1
结构分析(WXML)
组件结构:
-
使用navigation-bar自定义导航栏,显示标题。
-
外层容器.dropdown-container包含头部(.dropdown-header)和下拉列表(.dropdown-list)。
-
头部展示选中项/提示文字,右侧含删除图标和动态箭头。
数据绑定:
-
selectedItem控制显示选中内容,未选时显示“请选择校区”。
-
isDropdownOpen控制下拉列表展开状态,通过类名切换实现动画。
事件处理:
-
toggleDropdown:点击头部切换下拉状态。
-
selectItem:选择选项后更新选中项并关闭下拉。
-
delete:清空选中项,需处理事件冒泡。
<!--pages/selection/selection.wxml-->
<navigation-bar title="下拉选择框" back="{{false}}" color="black" background="#FFF"></navigation-bar>
<view class="dropdown">
<!-- 下拉菜单容器 -->
<view class="dropdown-container">
<!-- 下拉头部(显示选中项) -->
<view class="dropdown-header" bindtap="toggleDropdown">
<text class="selected-text">{{selectedItem || '请选择校区'}}</text>
<view class="dropdown">
<!-- 删除图标(有值时才显示) -->
<view wx:if="{{selectedItem}}" class="warning" catchtap="delete">⊗</view>
<!-- 箭头图标(带旋转动画) -->
<view class="arrow {{isDropdownOpen ? 'rotate' : ''}}">▼</view>
</view>
</view>
<!-- 下拉列表(含过渡动画) -->
<view class="dropdown-list {{isDropdownOpen ? 'open' : 'close'}}">
<view wx:for="{{dropdownItems}}" wx:key="index" class="dropdown-item {{item === selectedItem ? 'selected' : ''}}" bindtap="selectItem" data-item="{{item}}">
{{item}}
</view>
</view>
</view>
<view>
选择值:{{selectedItem || ''}}
</view>
</view>
逻辑分析(JS)
数据管理:
-
dropdownItems存储可选校区列表。
-
selectedItem和isDropdownOpen驱动视图变化。
事件冒泡问题:
- 删除按钮使用bindtap会触发父容器的toggleDropdown,导致状态冲突。原代码用setTimeout延迟关闭下拉,可能引发闪动。
// pages/selection/selection.js
Page({
/**
* 页面的初始数据
*/
data: {
isDropdownOpen: false,
selectedItem: null, // 初始为空
dropdownItems: ["中心校区", "红旗校区", "东风校区", "共青城校区", "CSDN奇妙方程式"]
},
// 切换下拉菜单
toggleDropdown() {
this.setData({ isDropdownOpen: !this.data.isDropdownOpen });
},
// 选择选项
selectItem(e) {
const item = e.currentTarget.dataset.item;
this.setData({
selectedItem: item,
isDropdownOpen: false // 选择后关闭下拉
});
},
// 删除所选值
delete() {
this.setData({
selectedItem: null,
isDropdownOpen: false // 关闭下拉
});
}
})
样式与动画(WXSS)
动画实现:
-
下拉列表通过max-height和opacity结合transition实现平滑展开/收起。
-
箭头使用transform: rotate配合过渡效果,旋转180度指示状态。
样式细节:
-
选中项高亮(.selected类)提升用户体验。
-
阴影和边框增强下拉框的层次感。
/* pages/selection/selection.wxss */
.dropdown {
display: flex;
align-items: center;
}
/* 下拉菜单容器 */
.dropdown-container {
margin: 20rpx;
width: 330rpx; /* 宽度可调 */
position: relative;
font-size: 28rpx;
color: #333; /* 文字颜色 */
}
/* 头部样式 */
.dropdown-header {
padding: 20rpx 24rpx;
background: #f8f8f8; /* 头部背景色 */
border-radius: 8rpx; /* 圆角 */
border: 1rpx solid #ddd; /* 边框 */
display: flex;
justify-content: space-between;
align-items: center;
}
/* 修改下拉列表动画部分 */
.dropdown-list {
max-height: 0;
opacity: 0;
overflow: hidden;
position: absolute;
top: 100%;
left: 0;
right: 0;
background: #fff;
border-radius: 8rpx;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1);
/* 更平滑的缓动函数 */
transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}
/* 展开状态 */
.dropdown-list.open {
max-height: 80vh;
opacity: 1;
}
/* 新增收起状态 */
.dropdown-list.close {
max-height: 0;
opacity: 0;
/* 更快的收起速度 */
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
/* 下拉选项 */
.dropdown-item {
padding: 20rpx 24rpx;
border-bottom: 1rpx solid #eee; /* 分割线 */
transition: background 0.2s;
}
/* 选中项高亮 */
.dropdown-item.selected {
background: #f0f0f0; /* 浅灰色背景 */
font-weight: 500;
}
/* 删除图标 */
.warning {
color: LightCoral;
}
/* 箭头图标 */
.arrow {
margin-left: 10rpx;
font-size: 24rpx;
transition: transform 0.5s ease;
color: #666;
}
/* 箭头旋转动画 */
.arrow.rotate {
transform: rotate(180deg);
}
json
{
"usingComponents": {
"navigation-bar": "/components/navigation-bar/navigation-bar"
}
}
部分代码由deepseek辅助生成