您当前的位置: 首页 > 解决方案

小程序云开发之踩到狗尾巴

  • 作者: admin
  • 发布于 2019-01-18 11:14:58
  • 来源:  
  • 栏目:解决方案

导语: 前段时间用了下快狗打车,感觉贼方便,师傅响应速度和服务态度都特别好,搬个家再也没有以前那么痛苦了,女票也是给了大大的赞。正好

 

前段时间用了下快狗打车,感觉贼方便,师傅响应速度和服务态度都特别好,搬个家再也没有以前那么痛苦了,女票也是给了大大的赞。正好最近毕业设计选题跟这个类似,参考了云开发文档,真心感觉云函数,云数据库,快且好用,立马开写,快快搞定毕设,好好工作(欢迎hr小姐姐楼层回复撩我)。不料,快速云开发之快狗毕设项目,犹如踩上了狗尾巴,坑坑真多,给各位像我一样,要快速写毕设,快速听女票话搬家的同学,记录一下。

先给你们看下运行效果:

09.gif

一、程序骨架的基本构建

1.功能的完整实现

做个东西首先就是要把它的基本功能实现了,这个是毋庸置疑的。如果你是自己准备做个自己的小 程序,那么你肯定要对自己的小程序应该实现怎样的功能了如指掌,在心里应该把实现功能的流程 预演个几百遍了。

这里第一个坑就出现了,我做的那会可没有想这么多,毕竟作为一个愣头青,莽 就完事了,从想法出来到开始动手时间不到1个小时,事实证明这是非常非常不可取的,也充分暴露 了我经验的不足。如果你不想像我一样写到后面一步一坑的话,最好提前想好。

2.页面的基本构建

作为一个较大的项目,主页结构应该做到结构清晰,语义化良好,尽量使用BEM命名规范,当然你要 是想你的代码写完后自己都看不懂,你就瞎**命名当我没说。

整个页面大概采用什么布局也要事先 想想清楚,当然手机端一般都是弹性布局比较好,让你的页面元素可大可小,完美适配不同尺寸的 手机。

布局的时候千万不要舍不得用盒子,如果把布局比作是整理衣柜的话,当你的衣服足够 多的话,一两个衣柜显然是无法满足条件的,你的衣服将被堆在一起,凌乱不堪。但是如果你有足 够的衣柜来放置衣服的话,你的衣服将被分门别类放置的整整齐齐。

在本小程序中,主页的弹性布 局是将地图部分设置为 flex:1 ,让地图高度随手机大小来变化,而其他部分保持不变来实现的。 但是在实际运行中,却总是出现各种问题,最终我的解决办法是再在页面中总出问题的部分加入了 一个盒子,又在弹性布局里嵌套了一个弹性布局,这样首页的适应性布局就完美实现了。

3.数据库的设计

云开发的发布,让后端对于数据的操作变的更简单了。微信小程序本质上是数据驱动页面,所以你 想在页面上展示什么,就设置一个对应的数据去关联。然后当我们想改变页面的时候,只需要改动 数据就可以了。由于我这个小程序数据比较简单,并没有把所有的数据都放在云端,我只建立一张 订单表orders。

13.jpg

因为订单里展示的信息不多所以只有‘时间’‘发货地’‘收货地’‘价格’几个属性,‘isdone’是用来标 记订单是否完成的,表现在页面中就是订单状态会显示‘已完成’或者‘已取消’

4. 选个好组件库

这个不是必须的,但是有时候选择到一个适合的组件库用起来真的爽,可以让你的开发事半功倍 我选的是vant(这个我选的就不是很好),希望你能选上一个让你用完发出一句真香感慨的。

二、程序功能的基本实现

如果你已经完成了上面的前三步,那你简直比我好太多了!剩下的只不过是将功能一个一个添加上 去罢了。由于本程序的实现使用了大量api,我不会去把这些api一个个详细讲解,这样纯粹是浪费 时间。但是我会把一些实现想法和一些我遇到的坑像大家说明,避免你们像我一样踩坑。

1. 实时获取点的坐标并将地址显示在页面

仔细看了演示图的同学会发现当我移动地图时,起点的地址是在实时发生变化的,当我停止拖动 地图时,起点的地址就会更新到最新点。那么这个功能是如何实现的呢?其实这里是有一点巧妙的。

实际上我用cover-image在地图上标记了一个起点,这个点是一直垂直居中固定在地图的中心的 。这样我只需要获取这个中心点的坐标并使用逆地址解析就能得到这个点的位置描述啦,是不是有 点巧妙。而怎么获取中心点的坐标和完成逆地址解析呢,当然这一切都有腾讯爸爸提供给我们的ap i去完成了。这里有个注意的点就是我们应在用户松开时来显示更新后的地址,bindregionchang这 个可以做到,当 e.type = end 时再显示就可以了,细节虽然小,但是还是不能忽视了。

2. 输入地址时要能有模糊搜索提示

12.gif

这个效果主要依赖于腾讯地图小程序jsSDK中的输入关键词提示,调用这个接口我们将可以在返回 值中拿到一个数组,里面包含着我们需要的各种信息。拿到数据是很简单的,但是如何处理它呢? 这个数组的长度是不固定的,其实很简单我们只需要将拿到的数据setData给一个我们定义的空数 组searchresult,这样所有的数据就到了这个数组里,到时候再去页面上循环这个数组,这样我们 就可以将里面的数据都拿出来并让它们显示在它们该显示的地方,所以这部分的关键在wxml里,下 面是我写的:

<view class="content">   <scroll-view class="scrollcontent" scroll-y style="height: {{scrollheight}}rpx;">     <block wx:for="{{searchresult}}" wx:key="index">       <van-cell-group border="{{true}}">         <van-cell class="resultlist" title="{{item.title}}" border="{{true}}" data-title="{{item.title}}"         data-location="{{item.location}}" icon="location" label="{{item.address}}" bind:click="getlistvalue"/>       </van-cell-group>     </block>   </scroll-view> </view> 复制代码

3.主页车型切换并带来价格的变化

这个需求是让顾客可以自由选择车型,这个有点类似滴滴打车的‘快车’'拼车'‘优享’。刚开始做的 时候我以为这是一个scroll-view和scroll-into-view配合来实现的。等到我把一切基本都实现了的 时候,最后一个效果就是实现滑动切换时划过一定距离就自动进入下一页,不够据距离就回弹。我 想了很多方法来判断,各种js判断各种利用scroll-left都搞不定。

直到我无意中在官方文档中看到 了swiper这个组件,这丝般顺滑的滑动切换,距离够了自动下一页,不够就回弹,这不就正是我所 需要的吗,于是我直接删了原来的代码,花了不到半个小时就撸完了这个小组件(核心在于判断cur renttab与index是否相等,注意这个index后面还有大用)。

看到这完美效果的我不禁泪流满面。所 以这件事告诉我们当你一直搞不定某个效果时,你应该静下心来想想是不是你开始就弄错了方向, 避免做无用功,浪费时间。接下来奉上我完美实现的代码(wxml和js部分):

wxml:

<view class="container">     <view class="container-header">     <view class="carLists {{currentTab === index ?'on': ''}}" wx:for="{{carName}}" wx:key="index" data-id="{{item.id}}" data-index="{{index}}" bindtap="switchTab">       {{item.name}}     </view>     </view>     <block wx:if="{{index>0}}">         <van-icon name="arrow-left" class="arrow-left" bind:click="last" />     </block>     <block wx:if="{{index<3}}">         <van-icon name="arrow" class="arrow" bind:click="next" />     </block>     <swiper class="carList" current="{{currentTab}}" bindchange="swiperChange">       <block wx:for="{{cars}}" wx:key="index">         <swiper-item class="carview">           <image class="carImg" src="{{item.image}}" mode="aspectFill"/>         </swiper-item>       </block>     </swiper>   </view> 复制代码

js:

switchTab:function(e){
      if (this.data.currentTab === e.target.dataset.index) {
        return;
    } else {
        this.setData({
            currentTab: e.currentTarget.dataset.index,
            index:e.currentTarget.dataset.index
        })
    }
  },
  
  
  swiperChange:function(e){
    // console.log( e.detail)
    if(e.detail.source == 'touch'){
      this.setData({
        currentTab: e.detail.current,
        index:e.detail.current
    })
    }
   
  },
    next:function(e){
      // console.log(this.data.currentTab,this.data.currentTab)
       if (this.data.currentTab === this.data.index && this.data.currentTab <3 ) {
          this.setData({
            currentTab:this.data.currentTab + 1,
            index:this.data.index +1
          })
        }
       
    },
  
    last:function(e){
      if (this.data.currentTab === this.data.index && this.data.currentTab > 0 ) {
        this.setData({
          currentTab:this.data.currentTab - 1,
          index:this.data.index -1
        })
      }
    }
复制代码

4.关于距离及价格的计算

之前在输入起点和终点的时候我们可以通过腾讯地图的api拿到两者的具体坐标,这里我采用的距 距离计算没有采用腾讯地图所提供的api(因为有距离限制,仅限10km以内),这个距离对于我们来说 无疑是太短了,于是我采取了一个通用公式,只要能有两地坐标,便可以算出两地间的距离,这样 一来我们的老司机们就不用再受到距离的限制了。

//计算两坐标点之间的距离
      distance: function (lat1, lng1, lat2, lng2) {
        const rad1 = lat1 * Math.PI / 180.0;   
        const rad2 = lat2 * Math.PI / 180.0;   
        const a = rad1 - rad2;   
        const b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;  
        const r = 6378137;
        const distance = (r * 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(rad1) * Math.cos(rad2) * Math.pow(Math.sin(b / 2), 2)))).toFixed(0)
        return distance / 1000;//单位转化为公里
      }
复制代码

现在我们拿到了距离,但是怎么能让价格根据所选车型来动态变化呢?还记得之前页面里给每个 滑块的index吗?这里我们恰好就可以用它来做一个switch判断,给getPrice函数传入一个index 参数判断不同值并给出不同的计价方式,这样一来价格变会随着车型的切换而变化了。最后我们 的效果就达到了。

11.gif

5.订单完成数据的上传及拉取

有了云开发之后数据库的操作简直不要太简单了!取消订单时,在选择完取消订单理由后,们 将向云数据库添加一条数据,只需几条命令我们就可以将我们的数据真正的存在数据库里并保存起 来,听上去是不是很心动呢

wx.cloud.init();//初始化
const db = wx.cloud.database();
const cancelOrder = db.collection('orders')//orders为手动在云数据库里添加的一张空表
//三步操作后我们就连上了我们的数据库
    cancelOrder.add({
      data:{
        time:globalData.time,
        shipAddr:globalData.address,
        receiveAdrr:globalData.receiveAdrr,
        price:globalData.price,
        isdone:false
      }
    })
复制代码

13.jpg

这样订单数据就被我们添加到了数据库里,可以被我们随时访问了。然后在通过一条简单的查 询语句就可以在我的订单里显示了。

orders.where({
      _openid:'xxxxxxxx'//用户的openid
    }).get({
      success: res=> {
        this.setData({
          orders:res.data
        })
        // console.log(res.data)
        wx.hideLoading();//加载完成关闭加载框
      }
    })
复制代码

最后在页面上循环输出orders里的值就可以得到一堆订单了

14.gif

写在最后

一个完整项目的实现确实不是那么简单的,即使是一个简单流程的实现,很多看似简单的东西 里经常藏着大坑,而不同页面之间的联系也是很让人头痛的,我们要从之前那种局部的眼光中跳脱 出来,从更大的层面来看待构建我们的项目骨架。

使用组件化,函数化的编程思想可以很好的帮助 我们降低代码的耦合性,增加代码的复用性,使我们的代码结构更清晰。写本篇文章的目的是为了 方便自己以后重构项目的时候看,也是为了给有跟我一样想法,跃跃欲试想撸个完整项目的同学一 个参考,少踩一些坑。

最后有什么建议或者文中有什么错误的地方欢迎在评论中指出,互相学习, 共同进步!

这是我在掘金发的第一篇文章,看完觉得还不错的同学点个赞再走吧!

完整项目点这: 项目地址

主要参考:

  1. 快狗打车拉货搬家微信小程序
  2. 微信小程序官方文档: developers.weixin.qq.com/miniprogram…
  3. 腾讯地图api文档: lbs.qq.com/qqmap_wx_js…
  4. vant Weapp小程序ui组件库: youzan.github.io/vant-weapp/…

 



温馨提示:这篇文章没有解决您的问题?欢迎添加微信:18948083295,有微信小程序专业人员,保证有问必答。转载本站文章请注明转自http://www.okeydown.com/(微信小程序网)。

  • 微信扫描二维码关注官方微信
  • ▲长按图片识别二维码
关注我们

微信小程序官方微信

栏目最新
栏目推荐
返回顶部