【微信小程序】联动菜单(左右侧菜单)实现
前言
最近为了实现课程设计,也做了一些前端的东西,今天想要做一个联动菜单来实现一些功能。实现了,也来做做笔记。
第1步:了解一下
联动菜单在微信小程序中常用于实现多级或多层级的选择功能,通过联动选择不同的选项来筛选和展示相关的数据或内容。一般实现方案包括以下几个步骤:
-
数据准备:准备数据源,通常是多个数据列表/字典,每个列表/字典对应一个级别的选择菜单。
-
菜单渲染:在小程序的页面中,使用组件或自定义样式实现联动菜单的渲染。一般来说,第一级菜单是初始化的入口,通过监听菜单选项的变化来获取对应的子级菜单数据,并更新后续级别的菜单选项。
-
事件监听:监听菜单选项的变化事件,当选择某个选项时,触发相应的事件处理函数。在处理函数中,根据当前选项的值,筛选获取下一级菜单的数据,并更新后续级别的菜单选项。
-
联动更新:根据用户的选择更新菜单数据。当用户选择了某个选项后,需要根据选择的值来筛选并获取下一级菜单的数据,然后根据数据更新下一级菜单的选项。在更新后续级别的菜单选项时,需要保留上一级已选择的值用于筛选。
-
数据展示:根据用户的选择和筛选结果,展示相应的数据或内容。可以根据联动菜单的最后一级选择值,从数据源中获取对应的数据,并展示给用户。
左右侧菜单其实简单来讲就是把一个区域分成左右两个部分。关于组件,我觉得可以直接去微信开发文档看。通过代码,我觉得应该是可以理解的。话步多讲,直接上代码。(首先说明一点的是,我还是个刚刚接触前端的小白,可能有些写得不太好得,往各位博友多多指出改进得建议,相互学习)
第2步:先看一下效果啦
为了节约大家的时间,这里我先放了实现效果,如果不是想要这种样式的可以直接划走,哈哈哈哈😂
下面是我实现的效果简单展示,样式可以后期自行优化,主要是JS交互部分:
这里因为我做的学校类的联动菜单,但是为了方便快速知道是一级菜单和二级菜单的联动,所以这里也用主类和子类进行说明了。
下面就是菜单的渲染及联动:
PS: 下面的部分我都是统一一样的,并不是没有替换哈
总体:运行效率还是可以的很快,无卡顿现象。
第3步:实现(代码)
这里我只放了其中一部分,也是可以直接实现的,没有问题,可以根据自己的需要修改。
- wxml
下面是关于联动菜单的wxml代码部分,这里采用的是float布局形式。
<!-- 左侧滚动栏 -->
<view class ='total'>
<view class='under_line'></view>
<view style='float: left' class='left'>
<scroll-view scroll-y scroll-with-animation scroll-left="{{scrollLength}}" class='scrollY' style='height: {{winHeight}}px'>
<view class='all clear'>
<block wx:key="lists" wx:for="{{lists}}">
<view bindtap='jumpIndex' data-menuindex='{{index}}'>
<view class='text-style'>
<text class="{{indexId==index?'active1':''}}">{{item}}</text>
<text class="{{indexId==index?'active':''}}"></text>
</view>
</view>
</block>
</view>
</scroll-view>
</view>
<!--右侧栏-->
<view class="right">
<!--判断indexId值显示不同页面-->
<view wx:if="{{indexId==0}}">
<scroll-view scroll-y scroll-with-animation scroll-left="{{scrollLength}}" class='scrollY2' style='height: {{winHeight}}px'>
<view class='all clear'>
<block wx:key="lists_r0" wx:for="{{lists_r0}}">
<view bindtap='jumpIndexR0' data-menuindex='{{index}}'>
<view class='text-style2'>
<text class="{{indexIdr0==index?'active2':''}}">{{item}}</text>
<text class="{{indexIdr0==index?'active3':''}}"></text>
</view>
</view>
</block>
</view>
</scroll-view>
</view>
<view wx:if="{{indexId==1}}">
<scroll-view scroll-y scroll-with-animation scroll-left="{{scrollLength}}" class='scrollY2' style='height: {{winHeight}}px'>
<view class='all clear'>
<block wx:key="lists_r1" wx:for="{{lists_r1}}">
<view bindtap='jumpIndexR0' data-menuindex='{{index}}'>
<view class='text-style2'>
<text class="{{indexIdr0==index?'active2':''}}">{{item}}</text>
<text class="{{indexIdr0==index?'active3':''}}"></text>
</view>
</view>
</block>
</view>
</scroll-view>
</view>
</view>
</view>
虽然这里采用的是float布局,但还要优化空间,比如使用 flexbox 布局或者基于自定义组件的组合方式。
- flexbox 布局的优点:
- 相对简单:flexbox 布局相对于传统的 float 布局来说更加简单易懂,通过设置容器及子元素的 flex属性可以轻松实现各种布局需求。
- 自适应:flexbox 布局可以根据容器的尺寸自动调整子元素的布局,适应不同屏幕大小和设备。
- 灵活性高:通过 flex 属性的设置,可以轻松控制子元素的宽度、高度、顺序及对齐方式,方便实现联动菜单的布局。
- 基于自定义组件的组合方式的优点
- 可复用性高:自定义组件具有较高的复用性,可以将多个组件进行组合、嵌套来构建联动菜单。
- 可维护性强:组件化开发可以让代码更加模块化,便于代码管理和维护。
- 可扩展性好:自定义组件可以接受外部传入的参数,可以方便地扩展组件的功能与样式。
- wxss
下面是关于联动菜单的wxss代码部分:
.under_line{
width: 100%;
border-top: 1rpx solid #efefef;
}
.left {
border-top: 1rpx solid #efefef;
border-right: 1rpx solid #efefef;
}
.text-style {
width: 200rpx;
height: 140rpx;
line-height: 140rpx;
text-align: center;
font-size: 34rpx;
font-family: PingFangSC-Semibold;
color: rgba(51, 51, 51, 1);
}
.active3 {
display: block;
width: 500rpx;
height: 6rpx;
background: rgb(88, 123, 193);
position: relative;
left: 0rpx;
bottom: 30rpx;
}
.active2 {
color: rgb(88, 123, 193);
}
.active1 {
color: #96C158;
}
.active {
display: block;
width: 50rpx;
height: 6rpx;
background: #96C158;
position: relative;
left: 75rpx;
bottom: 30rpx;
}
.scrollY {
width: 210rpx;
position: fixed;
left: 0;
top: 0;
border-right: 1rpx solid #efefef;
}
.right{
border-top: 1rpx solid #efefef;
border-left: 1rpx solid rgba(0,0,0,0.0);
margin-left: 2rpx;
}
.scrollY2 {
width: 520rpx;
position: fixed;
right: 0;
top: 0;
border-left: 1rpx solid rgba(0,0,0,0);
margin-left: 2rpx;
}
.text-style2 {
width: 520rpx;
height: 140rpx;
line-height: 140rpx;
text-align: left;
font-size: 34rpx;
font-family: PingFangSC-Semibold;
color: rgba(51, 51, 51, 1);
}
.button_call{
height: 90rpx;
width: 90rpx;
position: fixed;
bottom: 150rpx;
right: 13rpx;
opacity: 0.7;
z-index: 100;
}
- js
下面是关于联动菜单的js代码部分,可以看到下面主要采用的是多个列表来实现,但实际上这里还有很多优化空间。
Page({
/**
* 页面的初始数据
*/
data: {
lists: [
"主类1", "主类2", "主类3", "学生工作部", "党委部门", "校工与教务", "离退休工作处", "保卫处", "财务与审计", "实验室与设备", "人事处", "保卫处", "学院", "直属单位", "其他"
],
lists_r0: [
"主类1的子类1",
"主类1的子类2", "主类1的子类3", "主类1的子类4", "党委部门", "校工与教务", "离退休工作处", "保卫处", "财务与审计", "实验室与设备", "人事处", "保卫处", "学院", "直属单位", "其他"
],
lists_r1: [
"主类2的子类1",
"主类2的子类2", "主类2的子类3", "主类2的子类4", "党委部门", "校工与教务", "离退休工作处", "保卫处", "财务与审计", "实验室与设备", "人事处", "保卫处", "学院", "直属单位", "其他"
],
indexId: 0,
indexIdr0: 0,
indexIdr0: 1,
},
// 左侧点击事件
jumpIndex(e) {
let index = e.currentTarget.dataset.menuindex
let that = this
that.setData({
indexId: index
});
},
jumpIndexR0(e) {
let index = e.currentTarget.dataset.menuindex
let that = this
that.setData({
indexIdr0: index
});
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
var that = this
wx.getSystemInfo({
success: function(res) {
that.setData({
winHeight: res.windowHeight
});
}
});
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function() {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function() {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function() {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function() {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function() {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function() {
}
})
- json
下面是关于联动菜单的json配置部分:
{
"usingComponents": { },
"navigationBarBackgroundColor":"自己想要的背景色",
"navigationBarTitleText": "电话查询",
"navigationBarTextStyle":"black",
"enablePullDownRefresh": true
}