微信小程序菜单实现

最近一个月都在做微信小程序,作为一个Android开发者,在这一个月很少写Android的代码,真是悲催,好在现在已经完整的把小程序做完了,下周就继续开始我的Android生涯了,现在回过头来写写自己认为比较常见的一些功能的实现,来帮助小程序学习爱好者学习参考。今天的这篇文章是关于微信小程序菜单的实现,话不多说,上图。

menu1.gif

源码传送门

通过效果图,我们看到,窗口最上面是两个菜单按钮,它是固定悬浮在最上面,当点击时分别显示状态选择和时间选择,那此处状态就是我们购物订单的状态,有全部,待付款,等,并且当前选中的状态加上红色的边框,让用户知道当前的选择项。那点击时间时就显示显示开始日期和结束日期,当点击确定时对当前日期时间段的购物订单进行过滤。

状态和时间菜单按钮实现

菜单按钮实现很简单,使用display:flex属性,使用position: fixed将其定位窗口显示 top: 0;left: 0;悬浮在最上面。上下都加上边框。

  <view class="top-menu">
    <view bindtap="showMenuTap" data-type="1">状态</view>
    <view class="line"></view>
    <view bindtap="showMenuTap" data-type="2">时间</view>
  </view>

样式

.top-menu {
  display: flex;
  position: fixed;
  height: 80rpx;
  z-index: 10;
  background-color: #fff;
  width: 100%;
  top: 0;
  left: 0;
  align-items: center;
  justify-content: space-around;
  border-top: 2rpx solid #ddd;
  border-bottom: 2rpx solid #ddd;
  font-size: 11pt;
  color: #bdbdbd;
}

.line {
  width: 2rpx;
  height: 100%;
  background-color: #ddd;
}

两个菜单中间的分割线,我使用了一个view,当然依然可以使用border属性。在此处给加个z-index属性。稍后会介绍到他的作用。

弹出菜单实现

<view wx:if="{{menuType==1}}" class="state-menu "  hidden="{{!isVisible}}">
  <view class="state-item {{status==1?'border':''}}" bindtap="selectState" data-status="1">全部</view>
  <view class="state-item {{status==2?'border':''}}" bindtap="selectState" data-status="2">待付款</view>
  <view class="state-item {{status==3?'border':''}}" bindtap="selectState" data-status="3">待发货</view>
  <view class="state-item {{status==4?'border':''}}" bindtap="selectState" data-status="4">配送中</view>
  <view class="state-item {{status==5?'border':''}}" bindtap="selectState" data-status="5">待收货</view>
  <view class="state-item {{status==6?'border':''}}" bindtap="selectState" data-status="6">待评价</view>
  <view class="state-item {{status==7?'border':''}}" bindtap="selectState" data-status="7">退款</view>
  <view class="state-item {{status==8?'border':''}}" bindtap="selectState" data-status="8">已取消</view>
</view>
<!--日期选择-->
<view wx:elif="{{menuType==2}}" class="state-menu" hidden="{{!isVisible}}">
  <view class="date">
    <view class="classname">开始日期: </view>
    <picker mode="date" value="{{date}}" data-type="1" bindchange="bindDateChange">
      <view class="classname">{{begin==null?'不限':begin}}</view>
    </picker>
  </view>
  <view class="date">
    <view class="classname">结束日期: </view>
    <picker mode="date" value="{{date}}" data-type="2" bindchange="bindDateChange">
      <view class="classname">{{end==null?'不限' : end}}</view>
    </picker>
  </view>
  <button class="date-btn" bindtap="sureDateTap">确定</button>
</view>

样式

.state-menu {
  display: flex;
  position: fixed;
  left: 0;
  height: 200rpx;
  top: 80rpx;
  width: 100%;
  z-index: 9;
  background-color: #fff;
  flex-direction: row;
  border-bottom: 2rpx solid #ddd;
  justify-content: space-around;
  align-items: center;
  flex-wrap: wrap;
}
.state-item {
  width: 20%;
  height: 70rpx;
  font-size: 11pt;
  line-height: 70rpx;
  text-align: center;
  border-radius: 10rpx;
  border: 2rpx solid #ddd;
}

.border.state-item {
  border: 2rpx solid #c4245c;
}

.date {
  min-width: 40%;
  display: flex;
  font-size: 11pt;
  color: #bdbdbd;
  align-items: center;
}

.date-btn {
  min-width: 80%;
  font-size: 12pt;
  background-color: #c4245c;
  color: #fff;
}

弹出菜单我们设置高度为200rpx,依然使用position属性fixed将其固定在菜单按钮下面,由于菜单按钮我们设置的高度是80rpx,为了显示在菜单按钮下面,我们将top设置为80rpx.flex-wrap指定为wrap作用就是当item超出屏幕宽度时自动换行。由于我们设置状态的state-item的宽度为20%,所以当显示四个item时会换新行显示(五个item100%再加上border会超过宽度,所以第五个在新行显示(使用box-sizing: border-box,可让border宽度输入item的宽度,即item的20%包含border宽度))。

picker 组件是底部弹起的滚动选择器,现支持三种选择器,通过mode来区分,分别是普通选择器(mode = selector),时间选择器(mode = time),日期选择器(mode = date),默认是普通选择器,所以我们在此处设置mode = date。并且可以通过start设置有效日期范围的开始,字符串格式为"YYYY-MM-DD",通过end设置有效日期范围的结束,字符串格式为"YYYY-MM-DD"。选择的日期通过e.detail.value获得。

透明蒙版效果

当我们使用系统组件picker 弹出选择器时,我们会看到有一个透明的蒙版效果,那么我们也实现一个蒙版效果

<view class="dialog-mask" style="visibility:{{isVisible ? 'visible':'hidden'}}" bindtap="hideMenuTap" />

样式

.dialog-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 8;
  background: rgba(0, 0, 0, 0.3);
}

我们给蒙版设置了一个点击事件当点击时直接隐藏弹出菜单,样式使用了position:fixed属性,并将top,left,right,bottom都设置为0,即将蒙版全屏显示,设置背景黑色,透明的为0.3.此处依然使用了 z-index, z-index是z轴显示的深度,值越大,离我们越近,即值大会显示在值小的上面。所以我们将蒙版 z-index设置为8,菜单按钮设置为10,弹出菜单设置为9.这样也就看到文章开头图中的效果。

动画实现

通过上面的实现,已经可以达到我们想要的效果,但是显示和隐藏的时候比较突兀,我们再给它加点动画,动画的实现其实很简单,在这里介绍两种实现动画的方式,第一个是直接使用在样式文件wxss中实现,另一种是通过微信小程序提供的动画Api实现。
需要注意的是如果添加动画不能使用hidden属性显示隐藏弹出菜单,而是使用visibility,否则看不到动画效果。
样式文件wxss实现方式:

.hidden.state-menu {
  transform: translateY(-200rpx);
  transition: all 0.4s ease;
  visibility: hidden;
}

.show.state-menu {
  transform: translateY(0);
  transition: all 0.4s ease;
  visibility: visible;
}
<view wx:if="{{menuType==1}}" class="state-menu {{isVisible?'show':'hidden'}}">

API createAnimation创建动画方式

微信小程序提供了createAnimation创建动画,包括平移,旋转,缩放,倾斜等,并且实现方式简单,在这里就不在详细介绍API了,具体可参看官方文档

//定义变量
var animation
//在page中data中加入变量
animationData: {}
//onLoad初始化变量animation 
 var animation = wx.createAnimation({
      duration: 500,
      transformOrigin: "50% 50%",
      timingFunction: 'ease',
    })
    this.animation = animation;

// 执行动画函数
  startAnimation: function (isShow, offset) {
    var that = this
    var offsetTem
    if (offset == 0) {
      offsetTem = offset
    } else {
      offsetTem = offset + 'rpx'
    }
   //translateY可以加入单位(如20+'rpx'或者20+'vh',不写单位时默认px),当0时不能加单位,否则动画无效果
    this.animation.translateY(offset).step()
    this.setData({
      animationData: this.animation.export(),
      isVisible: isShow
    })
  },

然后只需要在view标签中加入animation="{{animationData}}"就可以看到动画效果了。到这里,已经实现了所以效果,当然侧滑,或者从下面弹出,等都可以通过这个思想实现。文中js的一些逻辑代码没在文中贴出,代码我已上传Github,可以前往查看

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,081评论 4 62
  • 今天参加了家长会,首先是陈校长讲话,讲了学校的师资、变化、管理、还有家校合育存在的一些问题和收获,说起厦小最近取得...
    李宇航妈妈阅读 249评论 0 0
  • 话说当年填志愿的时候,我的同桌跟我说她们家有个亲戚是做什么什么工作的,所以她要写某个志愿,方便以后工作,我当时还嗤...
    张阿狗阅读 324评论 2 1
  • 初中同学兼同桌好朋友,为在去年的时候辞职在家没有工作,于是在微信上和我联系,需要一份工作,要来我工作的地方上班...
    梁城凉梦凉人心阅读 374评论 2 2
  • 第二次营销策划开课了!看着很多熟悉又陌生的面孔再次走进系统内心深深的被先生的智慧所折服!赢家真的是一个超级...
    落子无悔ss阅读 229评论 0 0