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

前言

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

先给大家看下运行效果:git

1、程序骨架的基本构建

1.功能的完整实现

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

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

2.页面的基本构建

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

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

布局的时候千万不要舍不得用盒子,若是把布局比做是整理衣柜的话,当你的衣服足够 多的话,一两个衣柜显然是没法知足条件的,你的衣服将被堆在一块儿,凌乱不堪。可是若是你有足 够的衣柜来放置衣服的话,你的衣服将被分门别类放置的整整齐齐。后端

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

3.数据库的设计

云开发的发布,让后端对于数据的操做变的更简单了。微信小程序本质上是数据驱动页面,因此你 想在页面上展现什么,就设置一个对应的数据去关联。而后当咱们想改变页面的时候,只须要改动 数据就能够了。因为我这个小程序数据比较简单,并无把全部的数据都放在云端,我只创建一张 订单表orders。api

由于订单里展现的信息很少因此只有‘时间’‘发货地’‘收货地’‘价格’几个属性,‘isdone’是用来标 记订单是否完成的,表如今页面中就是订单状态会显示‘已完成’或者‘已取消’数组

4. 选个好组件库

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

2、程序功能的基本实现

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

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

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

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

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

这个效果主要依赖于腾讯地图小程序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 参数判断不一样值并给出不一样的计价方式,这样一来价格变会随着车型的切换而变化了。最后咱们 的效果就达到了。

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
      }
    })
复制代码

这样订单数据就被咱们添加到了数据库里,能够被咱们随时访问了。而后在经过一条简单的查 询语句就能够在个人订单里显示了。

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

最后在页面上循环输出orders里的值就能够获得一堆订单了

写在最后

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

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

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

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

完整项目点这:项目地址

主要参考:

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