微信小程式選單實現

Code4Android發表於2017-07-09

最近一個月都在做微信小程式,作為一個Android開發者,在這一個月很少寫Android的程式碼,真是悲催,好在現在已經完整的把小程式做完了,下週就繼續開始我的Android生涯了,現在回過頭來寫寫自己認為比較常見的一些功能的實現,來幫助小程式學習愛好者學習參考。今天的這篇文章是關於微信小程式選單的實現,話不多說,上圖。

menu1.gif
menu1.gif

原始碼傳送門

通過效果圖,我們看到,視窗最上面是兩個選單按鈕,它是固定懸浮在最上面,當點選時分別顯示狀態選擇和時間選擇,那此處狀態就是我們購物訂單的狀態,有全部,待付款,等,並且當前選中的狀態加上紅色的邊框,讓使用者知道當前的選擇項。那點選時間時就顯示顯示開始日期和結束日期,當點選確定時對當前日期時間段的購物訂單進行過濾。

狀態和時間選單按鈕實現

選單按鈕實現很簡單,使用display:flex屬性,使用position: fixed將其定位視窗顯示 top: 0;left: 0;懸浮在最上面。上下都加上邊框。

 &ltview class="top-menu">
    &ltview bindtap="showMenuTap" data-type="1">狀態&lt/view>
    &ltview class="line">&lt/view>
    &ltview bindtap="showMenuTap" data-type="2">時間&lt/view>
  &lt/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屬性。稍後會介紹到他的作用。

彈出選單實現

&ltview wx:if="{{menuType==1}}" class="state-menu "  hidden="{{!isVisible}}">
  &ltview class="state-item {{status==1?'border':''}}" bindtap="selectState" data-status="1">全部&lt/view>
  &ltview class="state-item {{status==2?'border':''}}" bindtap="selectState" data-status="2">待付款&lt/view>
  &ltview class="state-item {{status==3?'border':''}}" bindtap="selectState" data-status="3">待發貨&lt/view>
  &ltview class="state-item {{status==4?'border':''}}" bindtap="selectState" data-status="4">配送中&lt/view>
  &ltview class="state-item {{status==5?'border':''}}" bindtap="selectState" data-status="5">待收貨&lt/view>
  &ltview class="state-item {{status==6?'border':''}}" bindtap="selectState" data-status="6">待評價&lt/view>
  &ltview class="state-item {{status==7?'border':''}}" bindtap="selectState" data-status="7">退款&lt/view>
  &ltview class="state-item {{status==8?'border':''}}" bindtap="selectState" data-status="8">已取消&lt/view>
&lt/view>
&lt!--日期選擇-->
&ltview wx:elif="{{menuType==2}}" class="state-menu" hidden="{{!isVisible}}">
  &ltview class="date">
    &ltview class="classname">開始日期: &lt/view>
    &ltpicker mode="date" value="{{date}}" data-type="1" bindchange="bindDateChange">
      &ltview class="classname">{{begin==null?'不限':begin}}&lt/view>
    &lt/picker>
  &lt/view>
  &ltview class="date">
    &ltview class="classname">結束日期: &lt/view>
    &ltpicker mode="date" value="{{date}}" data-type="2" bindchange="bindDateChange">
      &ltview class="classname">{{end==null?'不限' : end}}&lt/view>
    &lt/picker>
  &lt/view>
  &ltbutton class="date-btn" bindtap="sureDateTap">確定&lt/button>
&lt/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 彈出選擇器時,我們會看到有一個透明的蒙版效果,那麼我們也實現一個蒙版效果

&ltview 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;
}
&ltview 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,可以前往檢視

相關文章