注冊

微信小程序開發(fā)之OFO共享單車,微信小程序掃描二維碼

2017-12-20
導讀:上一節(jié)我們實現(xiàn)首頁地圖,也響應了控件點擊和用戶拖動地圖事件。這一節(jié)我們實現(xiàn)一下點擊立即用車掃碼成功之后的頁面邏輯。 這里我用了我自己微信號的二維碼,你們可以用你們自...
上一節(jié)我們實現(xiàn)首頁地圖,也響應了控件點擊和用戶拖動地圖事件。這一節(jié)我們實現(xiàn)一下點擊立即用車掃碼成功之后的頁面邏輯。

這里我用了我自己微信號的二維碼,你們可以用你們自己的,掃碼成功后的頁面是醬的:


頁面分析
  • 后臺需要拿到開鎖密碼,然后顯示在頁面上
  • 我們需要一個定時器,規(guī)定多長時間用來檢查單車是否損壞,這期間如果單車故障,可以點擊回首頁去車輛報障,當然也就取消了本次掃碼。
  • 如果單車沒有問題,檢查時長完成后,自動跳轉到計費頁面


頁面布局
  1. <!--pages/scanresult/index.wxml-->
  2. <view class="container">
  3.     <view class="password-title">
  4.         <text>開鎖密碼</text>
  5.     </view>
  6.     <view class="password-content">
  7.         <text>{{password}}</text>
  8.     </view>
  9.     <view class="tips">
  10.         <text>請使用密碼解鎖,{{time}}s后開始計費</text>
  11.         <view class="tips-action" bindtap="moveToWarn">
  12.             車輛有問題?
  13.             <text class="tips-href">回首頁去車輛報障</text>
  14.         </view>
  15.     </view>
  16. </view>
復制代碼

微信小程序的頁面元素有自己的一套名字,用的是weui設計風格,但是元素種類比較少,比如說<view>就代表著<div>,<text>是行內元素,<image>是圖片標簽等,所以頁面標簽這一塊只要有html基礎就很容易理解

頁面樣式
  1. .container{
  2.         width: 100%;
  3.         display: flex;
  4.         flex-direction: column;
  5.         align-items: center;
  6.         justify-content: space-between;
  7.         background-color: #fff;
  8. }
  9. .password-title,.tips{
  10.         width: 100%;
  11.         flex: 1;
  12.         text-align: center;
  13.         padding: 60rpx 0;
  14. }
  15. .password-content{
  16.         width: 100%;
  17.         flex: 8;
  18.         text-align: center;
  19.         font-size: 240rpx;
  20.         font-weight: 900;
  21. }
  22. .tips{
  23.         font-size: 32rpx;
  24. }
  25. .tips .tips-action{
  26.         margin-top: 20rpx;        
  27. }
  28. .tips .tips-href{
  29.         color: #b9dd08
  30. }
復制代碼

樣式方面完全是css,注意這里的單位是rpx,是小程序為了自適應所有設備而設定的單位,按寬度為750px的設備計算,1rpx = 0.5px。其他比例換算可以看官方文檔。

先來了解兩個知識點:
  • 數(shù)據(jù)渲染頁面:前面我們在地圖組件中設置了數(shù)據(jù)模板,然后在js里通過服務器獲取數(shù)據(jù)動態(tài)給模板數(shù)據(jù)賦值,每當js數(shù)據(jù)改變,頁面就會重新渲染數(shù)據(jù)。所以核心思想是數(shù)據(jù)驅動頁面。我們在結構里設置了數(shù)據(jù)模板{{time}},說明這個數(shù)據(jù)是需要我們去改變的,所以先在data對象里賦予初始值9(為了調試方便,特意把時間調的很短)
  • 為元素綁定事件:和傳統(tǒng)html里不同,小程序頁面為元素綁定事件不能操作元素,不然就違背了數(shù)據(jù)驅動頁面的初衷,所以小程序在元素內聲明一個變量如 bindtap="moveToWarn"來為指定元素綁定點擊事件,然后在js里實現(xiàn)這個事件的功能。還可以綁定很多事件類型,更多可以查閱事件文檔


先來回頭看一下首頁地圖立即用車事件代碼,如果當前沒有在計費,將可以掃碼,掃碼成功后將會傳遞參數(shù)(密碼和車牌號)并跳轉到../scanresult/index,也就是本頁面。
  1. // 地圖控件點擊事件
  2.   bindcontroltap: function(e){
  3.     // 判斷點擊的是哪個控件 e.controlId代表控件的id,在頁面加載時的第3步設置的id
  4.     switch(e.controlId){
  5.       // 點擊定位控件
  6.       case 1: this.movetoPosition();
  7.         break;
  8.       // 點擊立即用車,判斷當前是否正在計費
  9.       case 2: if(this.timer === "" || this.timer === undefined){
  10.           // 沒有在計費就掃碼
  11.           wx.scanCode({
  12.             success: (res) => {
  13.               // 正在獲取密碼通知
  14.               wx.showLoading({
  15.                 title: '正在獲取密碼',
  16.                 mask: true
  17.               })
  18.               // 請求服務器獲取密碼和車號
  19.               wx.request({
  20.                 url: 'https://www.easy-mock.com/mock/59098d007a878d73716e966f/ofodata/password',
  21.                 data: {},
  22.                 method: 'GET',
  23.                 success: function(res){
  24.                   // 請求密碼成功隱藏等待框
  25.                   wx.hideLoading();
  26.                   // 攜帶密碼和車號跳轉到密碼頁
  27.                   wx.redirectTo({
  28.                     url: '../scanresult/index?password=' + res.data.data.password + '&number=' + res.data.data.number,
  29.                     success: function(res){
  30.                       wx.showToast({
  31.                         title: '獲取密碼成功',
  32.                         duration: 1000
  33.                       })
  34.                     }
  35.                   })           
  36.                 }
  37.               })
  38.             }
  39.           })
  40.         // 當前已經在計費就回退到計費頁
  41.         }else{
  42.           wx.navigateBack({
  43.             delta: 1
  44.           })
  45.         }  
  46.         break;
  47.       // 點擊保障控件,跳轉到報障頁
  48.       case 3: wx.navigateTo({
  49.           url: '../warn/index'
  50.         });
  51.         break;
  52.       // 點擊頭像控件,跳轉到個人中心
  53.       case 5: wx.navigateTo({
  54.           url: '../my/index'
  55.         });
  56.         break;
  57.       default: break;
  58.     }
  59.   },
復制代碼

我們在js里面寫下如下代碼,本頁面的options就是上面?zhèn)鬟f過來的參數(shù)。試試打印出來是什么!
  1. // pages/scanresult/index.js
  2. Page({
  3.   data:{
  4.     time: 9 // 默認計時時長,這里設短一點,用于調試,ofo app是90s
  5.   },
  6. // 頁面加載
  7.   onLoad:function(options){
  8.     // 獲取密碼
  9.     this.setData({
  10.       password: options.password
  11.     })
  12.     // 設置初始計時秒數(shù)
  13.     let time = 9;
  14.     // 開始定時器
  15.     this.timer = setInterval(() => {
  16.       this.setData({
  17.         time: -- time // 倒計時
  18.       });
  19.       // 讀完秒后攜帶單車號碼跳轉到計費頁
  20.       if(time = 0){
  21.         clearInterval(this.timer)
  22.         wx.redirectTo({
  23.           url: '../billing/index?number=' + options.number
  24.         })
  25.       }
  26.     },1000)
  27.   },
  28. // 點擊去首頁報障
  29.   moveToWarn: function(){
  30.     // 清除定時器
  31.     clearInterval(this.timer)
  32.     wx.redirectTo({
  33.       url: '../index/index'
  34.     })
  35.   }
  36. })
復制代碼

當?shù)褂嫊r完成之后,就應該自動跳轉到計費頁:
微信小程序開發(fā)之OFO共享單車,微信小程序掃描二維碼

頁面分析
  • 后臺需要拿到單車編號,并顯示在頁面上
  • 我們需要一個計時器累加騎行事件用來計費,而且可以顯示最大單位是小時
  • 兩個按鈕:結束騎行,回到地圖 。其中,點擊結束騎行,關閉計時器,根據(jù)累計時長計費;點擊回到地圖,如果計時器已經關閉了,就關閉計費頁,跳轉到地圖。如果計時器仍然在計時,保留當前頁面,跳轉到地圖。
  • 點擊回到地圖需要把計時器狀態(tài)帶給首頁,首頁做出判斷,判定再次點擊立即用車響應合理邏輯(已經在計費,不能重復掃碼。已經停止計費了,需要重新掃碼)


頁面結構(看看我們哪些是數(shù)據(jù)模板?,為元素綁定了什么事件?)
  1. <!--pages/billing/index.wxml-->
  2. <view class="container">
  3.     <view class="number">
  4.         <text>當前單車編號: {{number}}</text>
  5.     </view>
  6.     <view class="time">
  7.         <view class="time-title">
  8.             <text>{{billing}}</text>
  9.         </view>
  10.         <view class="time-content">
  11.             <text>{{hours}}:{{minuters}}:{{seconds}}</text>
  12.         </view>
  13.     </view>
  14.  
  15.     <view class="endride">
  16.         <button type="warn" disabled="{{disabled}}" bindtap="endRide">結束騎行</button>
  17.         <button type="primary" bindtap="moveToIndex">回到地圖</button>
  18.     </view>
  19. </view>
復制代碼

頁面樣式
  1. .container{
  2.         width: 100%;
  3.         display: flex;
  4.         flex-direction: column;
  5.         align-items: center;
  6.         justify-content: space-between;
  7.         background-color: #fff;
  8. }
  9. .number,.endride{
  10.         padding: 60rpx 0;
  11.         flex: 2;
  12.         width: 100%;
  13.         text-align: center;
  14. }
  15. .time{
  16.         text-align: center;
  17.         width: 100%;
  18.         flex: 6;
  19. }
  20. .time .time-content{
  21.         font-size: 100rpx;
  22. }
  23. .endride button{
  24.         width: 90%;
  25.         margin-top: 40rpx;
  26. }
復制代碼

數(shù)據(jù)邏輯(看注釋更好理解哦)
  1. // pages/billing/index.js
  2. Page({
  3.   data:{
  4.     hours: 0,
  5.     minuters: 0,
  6.     seconds: 0,
  7.     billing: "正在計費"
  8.   },
  9. // 頁面加載
  10.   onLoad:function(options){
  11.     // 獲取掃碼成功頁傳過來的車牌號,再定義一個定時器
  12.     this.setData({
  13.       number: options.number,
  14.       timer: this.timer
  15.     })
  16.     // 初始化計時器
  17.     let s = 0;
  18.     let m = 0;
  19.     let h = 0;
  20.     // 計時開始
  21.     this.timer = setInterval(() => {
  22.       this.setData({
  23.         seconds: s++
  24.       })
  25.       if(s == 60){
  26.         s = 0;
  27.         m++;
  28.         setTimeout(() => {         
  29.           this.setData({
  30.             minuters: m
  31.           });
  32.         },1000)      
  33.         if(m == 60){
  34.           m = 0;
  35.           h++
  36.           setTimeout(() => {         
  37.             this.setData({
  38.               hours: h
  39.             });
  40.           },1000)
  41.         }
  42.       };
  43.     },1000)  
  44.   },
  45. // 結束騎行,清除定時器
  46.   endRide: function(){
  47.     clearInterval(this.timer);
  48.     this.timer = "";
  49.     this.setData({
  50.       billing: "本次騎行耗時",
  51.       disabled: true
  52.     })
  53.   },
  54. // 攜帶定時器狀態(tài)回到地圖
  55.   moveToIndex: function(){
  56.     // 如果定時器為空
  57.     if(this.timer == ""){
  58.       // 關閉計費頁跳到地圖
  59.       wx.redirectTo({
  60.         url: '../index/index'
  61.       })
  62.     // 保留計費頁跳到地圖,帶上計時器狀態(tài)
  63.     }else{
  64.       wx.navigateTo({
  65.         url: '../index/index?timer=' + this.timer
  66.       })
  67.     }
  68.   }
  69. })

頁面分析的第4步,主要實現(xiàn)在moveToIndex函數(shù)里。結束騎行之后,設置定時器值為空,當點擊回到地圖時判斷計時器的狀態(tài)(值是否為空)。如果為空,關閉計費頁,結束本次騎行。如果不為空,攜帶定時器狀態(tài)跳轉到首頁,首頁立即用車點擊事件就會對傳過來的參數(shù)(計時器狀態(tài))響應合理邏輯。再回去上面看一下立即用車的判斷條件,當本頁面?zhèn)鬟^去的計時器不滿足條件時,我們在地圖首頁點擊立即用車將會回到本頁面

其他章節(jié)
微信小程序開發(fā)之OFO共享單車——掃碼
微信小程序開發(fā)之OFO共享單車——單車報障頁
微信小程序開發(fā)之OFO共享單車——個人中心頁
微信小程序開發(fā)之OFO共享單車——錢包與充值
重磅推薦:小程序開店目錄

第一部分:小商店是什么

第二部分:如何開通一個小商店

第三部分:如何登錄小商店

第四部分:開店任務常見問題

第五部分:小商店可以賣什么

第六部分:HiShop小程序特色功能

第七部分:小程序直播

第八部分:小程序收貨/物流

第九部分:小程序怎么結算

第十部分:小程序客服

第十一部分:電商創(chuàng)業(yè)

第十二部分:小程序游戲開發(fā)