微信小程序实现下拉框菜单附带遮罩层背景
实现功能
实现了点击按钮可以展开下拉选项菜单栏,并提供相关参自定义对应属性。
- 点击按钮弹出下拉菜单
- 自定义更改菜单文字颜色大小
- 包含遮罩层背景
- 新增功能1:自定义整个组件的层级
- 新增功能2:是否启用遮罩层背景
- 新增功能3:是否需要菜单标题(不加就不启用),且设置只显示4个字防止溢出
- 新增功能4:提供展开菜单和关闭菜单事件
- 新增功能5:提供两种样式
相关参数
options
展示的菜单列表
itemIndex
指定第一次选择的子项目
preTitle
菜单前置文字(如果不传则只显示menuTitle)
menuTitle
菜单名称(不传则默认第一个值)
menuColor
菜单栏文字颜色
menuSize
菜单栏文字大小
activeColor
选中的文字颜色
itemSize
选择的文字大小
zIndex
组件的层级
相关事件
bind:openMenu
打开菜单栏事件
bind:closeMenu
关闭菜单栏事件
bind:choose
选择子菜单事件
组件代码
dropdownMenu.wxml
<!--
@name:微信小程序下拉框菜单组件
@author: 柳吟风
@version: 1.0.0
-->
<!--
################各变量解释:
options: 展示的菜单列表
itemIndex: 指定第一次选择的子项目
preTitle: 菜单前置文字(如果不传则只显示menuTitle)
menuTitle: 菜单名称(不传则默认第一个值)
menuColor: 菜单栏文字颜色
menuSize: 菜单栏文字大小
activeColor: 选中的文字颜色
itemSize: 选择的文字大小
zIndex: 层级
isMask: 是否需要遮罩层背景
###############事件解释
bind:openMenu 打开菜单栏事件
bind:closeMenu 关闭菜单栏事件
bind:choose 选择子菜单事件
-->
<view class="container" style="z-index: {{zIndex}}">
<view bindtap="{{isMenuOpen?'closeMenu':'openMenu'}}" class="dropdown-title" style="font-size: {{menuSize}}rpx">
<view wx:if="{{preTitle}}" style="color: {{menuColor}}">{{preTitle}}:</view>
<text class="endEllipsis" style="color: {{activeMenu?activeColor:'#111'}}">{{activeMenu?options[choosed].text:menuTitle}}</text>
<text class="arrow {{isMenuOpen?'up': 'down'}}" />
</view>
<view class="dropdown-menu {{isMenuOpen ? 'open' : ''}}">
<block wx:for="{{options}}" wx:key="index">
<view class="menu-item" style="font-size:{{itemSize}}rpx;{{choosed==index? 'color: '+activeColor:''}}" bindtap="selectItem" data-item="{{item}}" data-index="{{index}}">
<view class="item-both">
<text>{{item.text}}</text>
<text wx:if="{{choosed==index}}" class="checkmark" />
</view>
</view>
</block>
</view>
</view>
<view wx:if="{{showMaskLayer&&isMask}}" class="mask" style="z-index: {{zIndex-1}};" bind:tap="{{isMenuOpen?'closeMenu':'openMenu'}}" />
dropdownMenu.js
Component({
/**
* 组件的属性列表
*/
properties: {
options: {
type: Array,
value: null
},
itemIndex: {
type: Number,
value: -1
},
preTitle: {
type: String,
value: null
},
menuTitle: {
type: String,
value: null
},
menuColor: {
type: String,
value: '#111'
},
menuSize: {
type: Number,
value: 32
},
activeColor: {
type: String,
value: "rgb(255, 69, 0)"
},
itemSize: {
type: Number,
value: 28
},
zIndex: {
type: Number,
value: 2
},
isMask: {
type: Boolean,
value: true
},
shrink: {
type: Boolean,
value: false
}
},
/**
* 组件的初始数据
*/
data: {
isMenuOpen: false,
choosed: -1,
showMaskLayer: false,
activeMenu: false
},
/**
* 组件的方法列表
*/
methods: {
/* 重置组件 */
resetMenu: function () {
this.setData({
choosed: -1,
activeMenu: false
})
},
/* 是否显示遮罩层阴影 */
showMask() {
this.setData({
showMaskLayer: true
});
},
/* 展开子菜单 */
openMenu: function () {
this.setData({
showMaskLayer: true,
isMenuOpen: true
});
// 给父组件传递事件
this.triggerEvent('openMenu')
},
/* 关闭子菜单 */
closeMenu: function () {
this.setData({
showMaskLayer: false,
isMenuOpen: false
});
// 给父组件传递事件
this.triggerEvent('closeMenu')
},
/* 选择子菜单内容 */
selectItem: function (e) {
let dataset = e.currentTarget.dataset
this.setData({
showMaskLayer: false,
isMenuOpen: false,
activeMenu: true,
choosed: dataset.index
})
// 给父组件传递数据
this.triggerEvent('choose', {
'index': dataset.index,
'item': dataset.item
})
}
},
lifetimes: {
ready() {
if (this.properties.menuTitle == null) {
this.setData({
choosed: 0,
activeMenu: true
})
}
let itemIndex = this.properties.itemIndex
if (itemIndex >= 0) {
this.setData({
choosed: itemIndex,
activeMenu: true
})
}
}
}
})
dropdownMenu.wxss
.container {
position: relative
}
.item-both {
display: flex;
align-items: center;
justify-content: space-between
}
.dropdown-title {
align-items: center;
display: flex;
background-color: #fff;
padding: 10rpx;
}
.endEllipsis {
display: -webkit-box;
word-break: break-all;
text-overflow: ellipsis;
/* 只显示4个字 */
width: 4em;
/* 溢出用省略号显示 */
overflow: hidden;
-webkit-line-clamp: 1;
/*设置需要显示的行数*/
-webkit-box-orient: vertical;
}
.dropdown-menu {
position: fixed;
top: auto;
/* 根据你的按钮高度和间距调整 */
left: 0;
right: 0;
/* 根据需要调整宽度 */
background-color: #fff;
/* 边框阴影 */
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
overflow: hidden;
/* 初始高度为0,用于隐藏菜单 */
max-height: 0;
overflow-y: auto;
/* 允许内容溢出时滚动 */
transition: max-height 0.3s ease-out, opacity 0.3s ease-out;
/* 初始透明度为0 */
opacity: 0;
}
.dropdown-menu.open {
/* 根据你的菜单项数量和高度调整 */
max-height: 260rpx;
/* 将透明度改为1进行显示 */
opacity: 1;
width: 100%;
}
.menu-item {
margin: 20rpx;
padding-bottom: 20rpx;
border-bottom: 1px solid #eee;
}
.menu-item:last-child {
border-bottom: none;
padding-bottom: 0;
}
/* 箭头 */
.arrow {
/* 跟左边文字有点距离 */
margin-left: 10rpx;
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
}
.arrow.up {
/* 可根据需求调整颜色 */
border-bottom: 10rpx solid rgb(187, 187, 187);
}
.arrow.down {
/* 可根据需求调整颜色 */
border-top: 10rpx solid rgb(187, 187, 187);
}
/* 勾的实现 */
.checkmark {
width: 20rpx;
height: 10rpx;
/* 设置勾的颜色 */
border-left: 4rpx solid rgb(255, 69, 0);
border-bottom: 5rpx solid rgb(255, 69, 0);
/* 旋转形成勾的形状 */
transform: rotate(-50deg);
}
/* 遮罩层 */
.mask {
position: fixed;
top: auto;
left: 0;
width: 100%;
height: 100%;
/* 半透明黑色背景 */
background-color: rgba(0, 0, 0, 0.5);
}
引用示例
index.wxml
<dropdownmenu options="{{options}}" pre-title="推荐" menu-title="热门目录" menu-size="28" item-size="28" bind:choose="chooseItem" bind:openMenu="closeOtherMenu" />
<dropdownmenu options="{{options}}" menu-title="热门目录" menu-size="28" item-size="28" bind:choose="chooseItem" bind:openMenu="closeOtherMenu" />
<dropdownmenu options="{{options}}" menu-size="28" item-size="28" bind:choose="chooseItem" bind:openMenu="closeOtherMenu" />
index.js
Page({
data: {
isMenuOpen: false,
options: [{
text: '新款手机',
value: 0
},
{
text: '旧款手机',
value: 1
},
{
text: '促销活动',
value: 2
},
{
text: '热卖商场',
value: 3
},
{
text: '低价专区',
value: 4
},
],
choosed: 0
},
/* 下拉框选择的数据 */
chooseItem(e) {
console.log(e)
}
});
index.json
{
"usingComponents": {
"dropdownmenu": "/components/dropdownMenu/dropdownMenu"
}
}
案例效果




2307

被折叠的 条评论
为什么被折叠?



