微信小程序开发之OFO共享单车,微信小程序扫描二维码

上一节我们实现首页地图,也响应了控件点击和用户拖动地图事件。这一节我们实现一下点击立即用车扫码成功之后的页面逻辑。

这里我用了我自己微信号的二维码,你们可以用你们自己的,扫码成功后的页面是酱的:


页面分析
  • 后台需要拿到开锁密码,然后显示在页面上
  • 我们需要一个定时器,规定多长时间用来检查单车是否损坏,这期间如果单车故障,可以点击回首页去车辆报障,当然也就取消了本次扫码。
  • 如果单车没有问题,检查时长完成后,自动跳转到计费页面


页面布局
  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。其他比例换算可以看官方文档。

先来了解两个知识点:
  • 数据渲染页面:前面我们在地图组件中设置了数据模板,然后在js里通过服务器获取数据动态给模板数据赋值,每当js数据改变,页面就会重新渲染数据。所以核心思想是数据驱动页面。我们在结构里设置了数据模板{{time}},说明这个数据是需要我们去改变的,所以先在data对象里赋予初始值9(为了调试方便,特意把时间调的很短)
  • 为元素绑定事件:和传统html里不同,小程序页面为元素绑定事件不能操作元素,不然就违背了数据驱动页面的初衷,所以小程序在元素内声明一个变量如 bindtap="moveToWarn"来为指定元素绑定点击事件,然后在js里实现这个事件的功能。还可以绑定很多事件类型,更多可以查阅事件文档


先来回头看一下首页地图立即用车事件代码,如果当前没有在计费,将可以扫码,扫码成功后将会传递参数(密码和车牌号)并跳转到../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就是上面传递过来的参数。试试打印出来是什么!
  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.     // 设置初始计时秒数
  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. })
复制代码

当倒计时完成之后,就应该自动跳转到计费页:
微信小程序开发之OFO共享单车,微信小程序扫描二维码

页面分析
  • 后台需要拿到单车编号,并显示在页面上
  • 我们需要一个计时器累加骑行事件用来计费,而且可以显示最大单位是小时
  • 两个按钮:结束骑行,回到地图 。其中,点击结束骑行,关闭计时器,根据累计时长计费;点击回到地图,如果计时器已经关闭了,就关闭计费页,跳转到地图。如果计时器仍然在计时,保留当前页面,跳转到地图。
  • 点击回到地图需要把计时器状态带给首页,首页做出判断,判定再次点击立即用车响应合理逻辑(已经在计费,不能重复扫码。已经停止计费了,需要重新扫码)


页面结构(看看我们哪些是数据模板?,为元素绑定了什么事件?)
  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. }
复制代码

数据逻辑(看注释更好理解哦)
  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. // 携带定时器状态回到地图
  55.   moveToIndex: function(){
  56.     // 如果定时器为空
  57.     if(this.timer == ""){
  58.       // 关闭计费页跳到地图
  59.       wx.redirectTo({
  60.         url: '../index/index'
  61.       })
  62.     // 保留计费页跳到地图,带上计时器状态
  63.     }else{
  64.       wx.navigateTo({
  65.         url: '../index/index?timer=' + this.timer
  66.       })
  67.     }
  68.   }
  69. })

页面分析的第4步,主要实现在moveToIndex函数里。结束骑行之后,设置定时器值为空,当点击回到地图时判断计时器的状态(值是否为空)。如果为空,关闭计费页,结束本次骑行。如果不为空,携带定时器状态跳转到首页,首页立即用车点击事件就会对传过来的参数(计时器状态)响应合理逻辑。再回去上面看一下立即用车的判断条件,当本页面传过去的计时器不满足条件时,我们在地图首页点击立即用车将会回到本页面

其他章节
微信小程序开发之OFO共享单车——扫码
微信小程序开发之OFO共享单车——单车报障页
微信小程序开发之OFO共享单车——个人中心页
微信小程序开发之OFO共享单车——钱包与充值
【本站声明】
  1、本站文章中所选用的图片及文字来源于网络以及用户投稿,由于未联系到知识产权人或未发现有关知识产权的登记,如有知识产权人并不愿意我们使用,如果有侵权请立即联系。
  2、本网站不对文章中所涉及的内容真实性、准确性、可靠性负责,仅系客观性描述,如您需要了解该类商品/服务详细的资讯,请您直接与该类商品/服务的提供者联系。


KESION 科汛软件

KESION 科汛软件是国内领先的在线教育软件及私域社交电商软件服务提供商,长期专注于为企业提供在线教育软件及社交电商SaaS平台解决方案。
公司核心产品云开店SaaS社交电商服务平台、在线教育SaaS服务平台、教育企业数字化SaaS云平台、企微营销助手、私有化独立部署品牌网校和在线教育咨询等。

KESION 不断通过技术创新,提供产品和服务,助力企业向数字化转型,通过科技驱动商业革新,让商业变得更智慧!



▼点击进入科汛官网了解更多



上/下篇
换一换相关推荐
精选内容
热点精选