介绍
多级联动菜单在许多的筛选场景应用十分广泛。
动手操作
先看看效果图:
-
总体布局
menu.wxml
<view class="menu">
<!-- 菜单导航 -->
<view class="menu_navi">
<view class="menu_navi_item" >
<text>游戏</text>
</view>
<view class="menu_navi_item">
<text>体育</text>
</view>
<view class="menu_navi_item">
<text>电影</text>
</view>
</view>
<!-- 某个菜单的内容 -->
<view class="menu_content">
<view class="menu_one">
<scroll-view class="left">
<view class="left_item">左边</view>
</scroll-view>
<scroll-view class="right">
<view class="right_item">右边</view>
</scroll-view>
</view>
<view class="menu_two" wx:if="{{menu_two_show}}">
<scroll-view class="left">
<view class="left_item">左边</view>
</scroll-view>
<scroll-view class="right">
<view class="right_item">右边</view>
</scroll-view>
</view>
<view class="menu_three" wx:if="{{menu_three_show}}">
<scroll-view class="left">
<view class="left_item">左边</view>
</scroll-view>
<scroll-view class="right">
<view class="right_item">右边</view>
</scroll-view>
</view>
<!-- 阴影部分 -->
<view class="surplus"></view>
menu.wxss
.menu{
position: fixed; /*固定位置*/
top: 0rpx;
left: 0rpx;
width: 100%;
display: flex;
flex-direction: column;
}
-
分模块进行开发
1、菜单导航
menu.jsp
<!--菜单导航-->
<view class="menu_navi">
<view class="menu_navi_item {{ menu_one_show ? 'menu_select':''}}" bindtap="menuOne" >
<text>游戏</text>
<icon class="iconfont {{ menu_one_show ? 'icon-unfold':'icon-fold'}}"></icon>
</view>
<view class="menu_navi_item {{ menu_two_show ? 'menu_select':''}}" bindtap="menuTwo">
<text>体育</text>
<icon class="iconfont {{ menu_two_show ? 'icon-unfold':'icon-fold'}}"></icon>
</view>
<view class="menu_navi_item {{ menu_three_show ? 'menu_select':''}}" bindtap="menuThree">
<text>电影</text>
<icon class="iconfont {{ menu_three_show ? 'icon-unfold':'icon-fold'}}"></icon>
</view>
</view>
menu.wxss
.menu_navi{
display: flex;
flex-direction: row;
width: 100%;
}
.menu_navi_item{
display: flex;
flex-direction: row;
justify-content: center; /*主轴居中 水平*/
align-items: center; /*侧轴居中 垂直*/
border: 1rpx solid #DCDCDC;
font-size: 30rpx;
width: 35%;
height: 80rpx;
}
/*菜单导航栏选中时,出现此样式*/
.menu_select{
color: brown;
background-color: springgreen;
}
menu.js
Page({
data: {
//游戏、体育、电影的显示与隐藏控制参数
menu_one_show: false, //控制菜单一的内容
menu_two_show: false, //控制菜单二的内容
menu_three_show: false, //控制菜单三的内容
},
/**
* 选项卡的控制
*/
//控制选项一
menuOne: function () {
var that = this;
if (that.data.menu_one_show) { //说明menu_one_show现在展开,需要关闭
that.setData({
menu_one_show: false,
menu_two_show: false,
menu_three_show: false,
})
} else {
that.setData({
menu_one_show: true,
menu_two_show: false,
menu_three_show: false,
select_left: select_left, //打开菜单的时候,默认选中的内容
select_left_content: that.data.menu_one_data[select_left],
select_right: '',
})
}
},
//控制选项二
menuTwo: function () {
var that = this;
if (that.data.menu_two_show) {
that.setData({
menu_one_show: false,
menu_two_show: false,
menu_three_show: false,
});
} else {
for (var select_top in that.data.menu_two_data) break; //第二个菜单栏的上部默认选中第一个,获得的是json的key值
var select_top_content = that.data.menu_two_data[select_top]; //默认选中第一个后的内容,提供下面进行使用
for (var select_left in select_top_content) break; //使用上面的内容,左边默认选中的第一个,而且也是获得它的key值,
var select_top_content = select_top_content[select_left]; //默认选中左边的时候,右边的内容进行显示。
that.setData({
menu_one_show: false,
menu_two_show: true,
menu_three_show: false,
select_top: select_top, //上方默认选择
select_top_content: that.data.menu_two_data[select_top], //选中上方之后,下方的内容
select_left: select_left, //左边的默认选择
select_left_content: select_top_content, //选中左边之后的,右边的内容
});
}
},
//控制选项三
menuThree: function () {
var that = this;
if (that.data.menu_three_show) {
that.setData({
menu_one_show: false,
menu_two_show: false,
menu_three_show: false,
})
} else {
that.setData({
menu_one_show: false,
menu_two_show: false,
menu_three_show: true,
select_left: select_left, //同游戏那个菜单
select_left_content: that.data.menu_three_data[select_left],
select_right: '',
})
}
},
2、多余部分
menu.wxml
<!-- 阴影部分 -->
<view class="surplus" wx:if="{{(menu_one_show)||(menu_two_show)||(menu_three_show)}}" bindtap="menuFlod"></view>
menu.wxss
.menu .surplus{
width: 100%;
height: 500rpx;
background-color: grey;
opacity: 0.8;
}
menu.js
// 点击阴影部分,菜单隐藏
menuFlod: function () {
var that = this;
that.setData({
menu_one_show: false,
menu_two_show: false,
menu_three_show: false,
})
},
4、具体菜单内容
这里主要针对一个菜单栏进行详细讲解,其余两个原理相同。
游戏
menu.wxml
<!-- 选项一 -->
<view class="menu_content">
<view class="menu_one" wx:if="{{menu_one_show}}">
<scroll-view class="left" scroll-y="true">
<view class="left_item {{select_left == key? 'select_left':''}} " wx:for="{{menu_one_data}}" wx:for-index="key" data-index="{{key}}" data-navi="1" wx:key="{{key}}" bindtap="selectLeft">
<text>{{key}}</text>
</view>
</scroll-view>
<scroll-view class="right" scroll-y="true">
<view class="right_item {{select_right == item? 'select_right':''}}" wx:for="{{select_left_content}}" data-index="{{item}}" wx:key="{{item}}" bindtap="selectRight">
<text>{{item}}</text>
</view>
</scroll-view>
</view>
</view>
这里推荐大家使用<scroll-view></scroll-view>组件,这样超过限定的高度的话,就可以在内部产生滚动条,整体布局不会乱。使用<scroll></scroll>组件的时候,记得要开启滚动的方向(scroll-y表示纵向,scroll-x表示横向),这些属性默认是关闭的。
menu.wxss
.menu_content{
width: 97.3%;
margin: 10rpx;
background-color: white;
}
.menu_one{
display: flex;
flex-direction: row;
width: 100%;
height: 600rpx;
}
..menu_one .left{
display: flex;
flex-direction: column;
width: 50%;
}
.menu_one .left .left_item{
padding: 15rpx;
line-height: 60rpx; /*设置成line-height自动垂直居中*/
}
.menu_one .left .select_left{
color: rgb(235, 79, 79);
background-color: #DCDCDC;
}
.menu_one .right{
display: flex;
flex-direction: column;
width: 50%;
}
.menu_one .right .right_item{
padding: 15rpx;
line-height: 55rpx;
background-color: #DCDCDC;
}
.menu_one .right .select_right{
color: rgb(235, 79, 79);
}
注意:使用竖向滚动时,需要给<scroll-view/>一个固定高度,通过 WXSS 设置 height。
menu.js
data: {
menu_one_data: {
"热门": ['冒险岛', '恋爱', '泡泡堂', '僵尸', '哆啦A梦', '海绵宝宝', '喜羊羊与灰太狼', '经营', '射击', '坦克', '合金弹头', '棋牌', '巧虎', '斗地主', '麻将', '女生' ,'拳皇', '森林冰火人'],
"益智": ['连连看', 'TD防守', '无敌连连看', '找茬', '模拟城市', '接水管', '斗地主', 'Nitrome', '对对碰', '华容道', '喜洋洋与灰太狼', '泡泡堂', '寻找小白人', '俄罗斯方块'],
"冒险": ['乖乖猪世界', '灵动', '男生', '魔域', '智能火柴人', '武林外传', '小王子冒险岛', '外星人大冒险', '神刀传奇', '小小冒险岛', '肥猫天使', '黑暗僵尸仓库', '救人', '蜘蛛侠'],
"战争": ['黑暗基地', '战争', '柏林飞机战争', '魔兽战争', '射击', '史诗幻想战役', '第一次世界大战', '合金弹头系列', '忍者与海盗', '火柴人战争', '冒险王', '午夜僵尸大战', '金刚狼'],
"动作": ['变态版', '松鼠大决战', '李小龙', '中国功夫', '明星大乱斗', '疯狂独轮车大战', '海绵宝宝空手道', '兔子杀戮', '拳皇wing', '悟空格斗', '火影忍者大乱斗', '泰拳小子'],
"敏捷": ['小鸟', '神奇小妖怪相关', '冒险', '死神', '祖玛', '暴力拆除', '洛克人', '索尼克', '森林冰火人', '植物大战僵尸相关', '模拟世界', '冒险岛', '黄金矿工', '动作', '三国'],
"女生": ['化妆', '换装', '打扮', '宝贝', '发型设计', '芭比娃娃', '明星' ,'爱情测试', '甜心姐妹美发', '婚礼婚纱', '精灵换装', '恋爱', '礼服' ,'可爱', '模拟世界', '开店经营' ,'设计布置', '美女'],
"专辑": ['动漫', '游戏', '哆啦A梦', '冒险岛系列', '虹猫蓝兔', '火影忍者' ,'少年骇客', '蜡笔小新', '史酷比系列', '蝙蝠侠', '降世神通Avatar', '海贼王系列' ,'拼图' ,'儿童', '西游记', '洛克人']
},
menu_three_data:{
"喜剧": ['憨豆先生精选辑', '美丽人生', '福尔摩斯二世', '顺其自然', '摩登时代', '城市之光', '三傻大闹宝莱坞', '疯狂动物城', '大话西游', '寻子遇仙记', '淘金记'],
"爱情": ['霸王别姬', '阿甘正传', '美丽人生', '泰坦尼克号', '巴黎圣母院', '罗密欧与朱丽叶', '我爱你', '断背山', '请以你的名字呼唤我', '幸福终点站'],
"科幻": ['盗梦空间', '星际穿越', '虚幻勇士', '蝙蝠侠:黑暗骑士', '楚门的世界', 'V字仇杀队', '黑客帝国', '蝴蝶效应', '人工智能'],
"纪录片": ['人生果实', '人生七年', '从纳粹手中救出的孩子们', '克拉玛依'],
"家庭": ['东京物语', '灿烂人生', '摔跤吧!爸爸', '我的父亲,我的儿子', '地上的星星', '大鱼', '金色池塘', '岁月神偷'],
"战争": ['辛德勒的名单', '战争与和平3', '鬼子来了', '沉静如海', '革命往事', '法国大革命', '拯救大兵瑞恩', '勇敢的心', '乱'],
},
select_left: '', //默认选中左边框的内容 (选中哪一项)
select_left_content:[], //选中左边框--->右边框的内容
select_right: '', //默认选中右边框边框的内容 (选中哪一项)
},
/**
* 点击左边框
*/
selectLeft: function (e) {
var that = this;
var select_left = e.currentTarget.dataset.index; //从wxml中传过来的数据,表示选中那个key
var select_left_content = []; //准备接收右边的内容
// 判断是哪个菜单栏
if ('1' == e.currentTarget.dataset.navi){
select_left_content = that.data.menu_one_data[select_left];
} else if ('2' == e.currentTarget.dataset.navi){
select_left_content = that.data.select_top_content[select_left];
} else {
select_left_content = that.data.menu_three_data[select_left];
}
console.log(select_left_content);
that.setData({
select_left: select_left,
select_left_content: select_left_content,
select_right: '',
})
},
/**
* 点击右边框
*/
selectRight: function(e){
var that = this;
var select_right = e.currentTarget.dataset.index;
that.setData({
select_right: select_right
})
},
menu.js部分主要的难点就是wxml和js之间的数据交互,这里很容易弄晕,尤其是对自己定义的变量弄清楚是什么意思。在这里小编画了一个示意图来讲解这个难点。
最后给大家提供该项目的github项目,直接抓下来就可以打开使用,只需对显示的数据进行修改即可。