dropdown.js
// components/dropdown/dropdown.js
Component({
properties: {
options: Array, // 选项列表
defaultValue: String // 默认显示文本
},
data:{
isVisible:false,
selected:''
},
methods:{
toggle() {
this.setData({ isVisible: !this.data.isVisible })
this.triggerEvent('toggle', { status: this.data.isVisible })
},
// 选择选项
select(e) {
const { value, label } = e.currentTarget.dataset
this.setData({
selected: label,
isVisible: false
})
this.triggerEvent('change', { value })
},
// 关闭菜单
close() {
this.setData({ isVisible: false })
}
}
})dropdown.wxml
<!-- components/dropdown/dropdown.wxml -->
<view class="dropdown">
<!-- 触发按钮 -->
<view class="trigger" bindtap="toggle">
{{ selected || defaultValue }}
<image
src="/images/san.png"
class="arrow {{isVisible ? 'up' : 'down'}}"
/>
</view>
<!-- 下拉内容 -->
<view class="panel" wx:if="{{isVisible}}">
<scroll-view scroll-y style="height: 400px;">
<block wx:for="{{options}}" wx:key="value">
<view
class="item {{selected === item.label ? 'active' : ''}}"
bindtap="select"
data-value="{{item.value}}"
data-label="{{item.label}}"
>
{{item.label}}
</view>
</block>
</scroll-view>
</view>
<!-- 遮罩层 -->
<view
class="mask"
wx:if="{{isVisible}}"
bindtap="close"
/>
</view>dropdown.wxss
/* components/dropdown/dropdown.wxss */
/* components/dropdown/dropdown.wxss */
.dropdown {
/* flex:1; */
display: flex;
align-items: center;
height:50rpx;
line-height: 50rpx;
/* text-align: center; */
}
.trigger {
flex:1;
padding: 20rpx;
/* border: 1rpx solid #eee; */
/* border-radius: 8rpx; */
display: flex;
align-items: center;
text-align: center;
/* justify-content: space-between; */
}
.arrow {
width: 24rpx;
height: 24rpx;
transition: transform 0.3s;
}
.arrow.down {
transform: rotate(0deg);
}
.arrow.up {
transform: rotate(180deg);
}
.panel {
position: absolute;
top: 280rpx;
width: 100%;
height: 400rpx;
background: white;
box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1);
z-index: 100;
left:0;
/* border:1px solid red;*/
overflow: hidden;
}
.item {
padding: 20rpx;
border-bottom: 1rpx solid #f5f5f5;
}
.item.active {
color: #07c160;
background: #f0fff8;
}
.mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.3);
z-index: 99;
}页面.js
// pages/tab/tab.js
Page({
/**
* 页面的初始数据
*/
data: {
options1: [
{ label: '北京', value: 'bj' },
{ label: '上海', value: 'sh' }
],
options2: [
{ label: '食品', value: 'food' },
{ label: '服饰', value: 'clothes' },
{ label: '食品1', value: 'food' },
{ label: '食品2', value: 'food' },
{ label: '食品3', value: 'food' },
{ label: '食品4', value: 'food' },
{ label: '食品5', value: 'food' },
{ label: '食品6', value: 'food' },
{ label: '食品7', value: 'food' },
{ label: '食品8', value: 'food' },
{ label: '食品8', value: 'food' },
{ label: '食品8', value: 'food' },
{ label: '食品8', value: 'food' },
{ label: '食品8', value: 'food' },
{ label: '食品8', value: 'food' },
{ label: '食品8', value: 'food' },
{ label: '食品8', value: 'food' },
{ label: '食品8', value: 'food' }
],
currentDropdown: null // 记录当前打开的菜单
},
// 切换菜单时触发
onToggle(e) {
const id = e.currentTarget.id
if (e.detail.status) {
// 关闭其他菜单
if (this.data.currentDropdown && this.data.currentDropdown !== id) {
this.selectComponent(`#${this.data.currentDropdown}`).close()
}
this.setData({ currentDropdown: id })
}
},
// 处理选择事件
onChange1(e) {
console.log('菜单1选中:', e.detail.value)
},
onChange2(e) {
console.log('菜单2选中:', e.detail.value)
},
/**
* 生命周期函数--监听页面加载
*/
onLoad(options) {
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage() {
}
}).dropdown-box{
display: flex;
flex-direction: row;
margin-top:100rpx;
}
.dropdown-box .dropdown1{
flex:1;
}
<view class="dropdown-box">
<!-- 第一个下拉菜单 -->
<dropdown
id="dropdown1"
class="dropdown1"
options="{{options1}}"
defaultValue="请选择城市"
bindchange="onChange1"
bindtoggle="onToggle"
/>
<!-- 第二个下拉菜单 -->
<dropdown
class="dropdown1"
id="dropdown2"
options="{{options2}}"
defaultValue="请选择分类"
bindchange="onChange2"
bindtoggle="onToggle"
/>
</view>