618购物节来袭,电商陪你浪浪浪

453 阅读9分钟

前言

购物节又要来啦!!(撒花撒花!)零食打折啦!!衣服打折了!!小伙伴们准备好买买买了吗!!!让我看看我还多少余额哈!(满心期待(* ̄︶ ̄))

(10秒后......)
好吧我还是写个电商小程序过过瘾好了。[冷漠脸]

咳咳,让我们进入正题。本人作为一个前端新手,终于完成了一个小项目——电商平台的开发——以此文记录一下我的开发历程,希望在自己总结的同时也能帮助到其他小伙伴。(大家一起加油啦~)

详细介绍


1、主页

话不多说先上动图



           (!上错了上错了!图在下面在下面!!!看官们千万别弃文![一本正经脸])

主页包括导航栏、轮播图、图标导航(中间那部分不知道应该怎么形容。。)以及底下用wx:for循环的商品列表。

  • 导航栏

    导航栏用的scroll-view组件,设置其水平方向滑动,点击到的字体会变换样式。而且,导航栏点击不同的类别会将主页替换成不同的结构,这就要将最开始的主页结构隐藏起来。我在data中设置 curTag: 0 (默认选中热门类别),点击各个类别会动态改变curTag值;再通过wx:if="{{curTag == 0}}"的判断来隐藏结构。

    代码如下:

    wxml

      <view class="Block1">
          <scroll-view class="block1" scroll-x="true">
              <view wx:for="{{tabblock}}" data-id="{{index}}" class="blk1tab {{curNav == index? 'selected': ''}}" bindtap="tabClick">{{item.name}}</view>
          </scroll-view>
          <block wx:if="{{curTag == 1}}"><include src="../one/one"/></block>
      </view>
    


    wxss

      .block1 .blk1tab {
          display: inline-block;
          font-size: 22rpx;
          color: #58595b;
          margin: auto 14rpx;
          padding-top: 20rpx;
          border-bottom: 2rpx solid transparent;
      }
      .block1 .selected {
          color: red;
          border-color: red;
      }
    


    js

      tabClick: function(e) {
          var id = e.currentTarget.dataset.id;
          this.setData({
              curNav: id,
              curTag: id
          });
      },
    

  • 图标导航

    图标来自于iconfont-阿里巴巴矢量图标库

    图标导航用的也是scroll-view组件,具体讲一下导航滑动时,下方红线进度条跟进的实现。
    红线移动即是要动态改变它在水平方向的位置,这是通过scroll-view组件中bindscroll事件实现的;事件触发时可在detail中查询到scrollLeft范围,根据范围再设置红线相应位置即可。

    代码如下:

    wxml

      <scroll-view class="scroll-view" scroll-x="true" bindscroll="scrollMove">
          <view class="block3_blk">
              <block wx:for="{{blkpic1}}">
                  <navigator class="blk3pic">
                      <image src="{{item.src}}" class="blkImage" />
                      <view class="blk3title">{{item.title}}</view>
                  </navigator>
              </block>
          </view>
          <view class="block3_blk">
              <block wx:for="{{blkpic2}}">
                  <navigator class="blk3pic">
                      <image src="{{item.src}}" class="blkImage" />
                      <view class="blk3title">{{item.title}}</view>
                  </navigator>
              </block>
          </view>
      </scroll-view>
      <view class="scroll-line">
          <view class="scrollMove" style="left:{{viewleft}}rpx"></view>
      </view>
    


    js

      scrollMove: function(e) {
          var left = e.detail.scrollLeft;
          this.setData({
          viewleft: left
          })
      },
    

2、商品详情页


详情页有轮播图、弹框和自定义的tabBar;轮播图我就不提了,下面总结下弹框和tabBar的实现。

  • 自定义tabBar

    要将tabBar固定在页面底部,只需在样式中将position设为fixed,再设置好left和bottom即可。值得注意的是,此处使用navigator标签跳转到tabBar首页,默认的跳转方式没法实现;需要将navigator的open-type设为switchTab。

    wxml如下:

      <navigator class="tabBar_box tabbox" url="../index/index" open-type="switchTab">
          <image class="tab_image" src="../../images/Gshouye.png"></image>
          <view class="tab_name">首页</view>
      </navigator>
    

  • 自定义弹框

    弹框这部分是两个结构,前面的信息面和后面透明的蒙层。弹框也是用fixed固定住,它的弹出效果可调用小程序api中的wx.createAnimation来实现。弹框弹出后,点击蒙层可以退出弹框;而在这里我还做了一个小细节:弹出后详情页不可滚动。

    贴上代码:

    wxml

      <view class="block_back" wx:if="{{block3click}}" bindtap="hideModal"></view>
      <view class="block3_out" wx:if="{{block3click}}" animation="{{animationData}}">
          <view class="blk_out_title">服务说明</view>
          <view class="blk_out_list">
              <view class="list_item" wx:for="{{lists}}">
                  <view>
                      <image src="{{item.src}}"></image>
                  </view>
                  <view class="list">
                      <text class="list_title">{{item.title}}</text>
                      <text class="list_cnt">{{item.content}}</text>
                  </view>
              </view>
          </view>
      </view>
    

    js

      serverContent: function(e) {
          var that = this;
          // console.log(e);
          var animation  = wx.createAnimation({
              // 动画持续时间
              duration:200,
              // 动画效果
              timingFunction:'linear'
          });
          that.animation = animation
          //在y轴偏移
          animation.translateY(400).step()
          // 让弹框出现
          that.setData({
              block3click: true,
              blockclick: true,
              animationData: animation.export()
          });
          setTimeout(function(){
              animation.translateY(0).step()
              that.setData({
                  animationData: animation.export()
              })
          },100)
       },
      //隐藏弹框
      hideModal: function() {
          this.setData({
          block3click: false,
          blockclick: false
          })
      }
    

    弹框出现禁止详情页滚动,即blockclick为true时设置overflow为hidden。

3、选择和支付页面

选择和支付页面存在许多数据交互,比如不同货号对应不同商品图;两个页面中的数据会相互影响,这里我还踩了几个小坑(踩坑有益进步┓( ´∀` )┏)让我慢慢总结。。。

  • 未选择提示

    这里没有选择货号就会出现上图的弹框,仍然是true or false的设置;没啥好讲哒,直接上代码啦。

    wxml

      <view class="confirm" bindtap="purchaseClick">确定</view>
      <view class="confirmOut" wx:if="{{showOut}}" animation="{{animationData}}">请选择货号</view>
    


    js

      purchaseClick: function() {
          //获取当前选中的货号
          var a = this.data.curNav;
          var that = this;
          //判断是否选中 为空则显示弹框
          if (a == null) {
              that.setData({
                  showOut: true
              }) 
          } else {
              wx.navigateTo({
                  url: '../pay/pay',
              })
          };
          var animation  = wx.createAnimation();
          //延时后隐藏弹框
          setTimeout(function(){
              that.setData({
                  animationData: animation.export(),
                  showOut: false
              })
          },1500)
      }
    

  • 选择页和支付页的数据交互

    首先是选择页的数据更新,此处都是通过wx:for循环数组来添加信息。
    头部的数组中只有一条元素,包括了图片、价格和货号信息,当选择了不同的货号后,就更替头部数组中的元素;请见代码:

    头部wxml:

      <view class="pur_hd" wx:for="{{purContent}}">
          <view class="tabBox pur_pic">
              <image class="goodspic" src="{{item.src}}"></image>
          </view>
          <view class="tabBox">
              <view class="price">¥{{item.price}}</view>
              <view class="content">{{item.title}}</view>
          </view>
      </view>
    

    头部js:

      //data中
      purContent: [
          {
              src: "//t00img.yangkeduo.com/t05img/images/2018-06-04/e5162f6d8e3ee7bc5620ae4f7c9c4a42.jpeg",
              price: "9.9-27.9",
              title: "请选择\xa0\xa0货号"
          }
      ]
    

    货号部分wxml:

      <view class="pur_bd">
          <view class="text">货号</view>
          <view class="modalLists {{curNav == index? 'selected' : ''}}" bindtap="selected" wx:for="{{modalLists}}" data-index="{{index}}" >{{item.content}}</view>
      </view>
    

    js

      //data中
      modalLists: [
          { 
              src: "//t03img.yangkeduo.com/images/2018-04-17/9b022a30f3a9f10b437a1e19defb20fb.jpeg",
              content:"蓝色经典18包" ,
              price: "20.26",
              title: "已选:蓝色经典18包"
          },
          { 
              src: "//t09img.yangkeduo.com/images/2018-04-17/1225b00e178d9042841170ca70e926b8.jpeg",
              content:"蓝色经典27包" ,
              price: "27.9",
              title: "已选:蓝色经典27包"
          },
          { 
              src: "//t07img.yangkeduo.com/images/2018-04-17/bcbca6f465fa5e2c1a5628ec10d69089.jpeg",
              content:"蓝色经典8包" ,
              price: "10.9",
              title: "已选:蓝色经典8包"
          },
      ]
      
      ......
      
      selected: function(e) {
          //获取当前点中的货号
          var index = e.currentTarget.dataset.index;
          //声明一个空数组
          var list = new Array;
          //将当前点中的货号数组元素添加到list数组中
          list[0] = this.data.modalLists[index];
          //更替头部purContent数组中元素
          this.setData({
              curNav: index,
              purContent: list,
          });
          //本地存储,为支付页传数据
          wx.setStorage({
              key: 'list',
              data: list[0]
          })
      }
    

    选择页完成后,其数据要传递给支付页,包括商品图、数量、价格和货号,同时支付页要统计商品总价。数据的传递我是通过本地存储完成的。将选择页的数据通过wx:setStorage进行存储,再在支付页用wx:getStorage获取数据,通过setData就可以将数据显示出来了。

    代码:

    wxml

      <view class="block3">
          <view class="block3_box">
              <image src="{{src}}"></image>
          </view>
          <view class="box block3_box">
              <view class="box content">27包18包8包 植护原木抽纸300张整箱批发家庭装3层抽去式面巾纸</view>
              <view class="box modal">货号:{{modal}}</view>
              <view class="box price">¥{{price}}/件</view>
          </view>
      </view>
      
      <view class="block5">
          <view class="block5_box box1">
              <text class="content1">实付款:</text>
              <text class="content2">¥{{total}}</text>
              <text class="content3">免运费</text>
          </view>
          <view class="block5_box box2" >
              <text>立即支付</text>
          </view>
      </view>
    


    js

      data: {
          modal: '',
          price: '',
          number: '',
          src: '',
          total: ''
      },
      //计算总价
      total: function() {
          var that = this;
          var number = that.data.number,
          var price = that.data.price;
          //.toFixed()保留几位小数
          var total = (number * price).toFixed(1);
          //显示数据
          that.setData({
              total: total
          })
      }
      
      ......
      
      //获取本地存储中数据
      var that = this;
      wx.getStorage({
          key: 'list',
          success: function(res){
              var modal = res.data.content;
              var price = res.data.price;
              var src = res.data.src;
              //更新数据
              that.setData({
                  modal: modal,
                  price: price,
                  src: src
              });
          //第一次加载时计算一下总价
          that.total()
          }
      })
    

    这里我加了一个.toFixed()方法,因为没加时数量变化会让小数精确度不一(好吧强迫症犯了,我觉得加了就好看多了hhhhh)。

  • 数量加减

    商品数量变化是双向的,在选择页的加减要更新到支付页,而在支付页改变数量后也要更新到选择页,这个效果的实现同样通过本地存储。

    wxml

      <view class="stepper">
          <!-- 减号 -->
          <view class="normal" data-index="{{index}}" bindtap="bindMinus">-</view>
          <!-- 数量 -->
          <view class="number">{{number}}</view>
          <!-- 加号 -->
          <view class="normal" data-index="{{index}}" bindtap="bindPlus">+</view>
      </view>
    


    js

          //减法 
          bindMinus: function() {
              // 字符串转数字类
              var num = parseInt(this.data.number);
              var that = this;
              if (num > 1) {
                  num = num - 1;
                  that.setData({  
                      number: num
                  })
              };
              //存储一下
              wx.setStorage({
                  key: 'number',
                  data: num
              })
          }
          
          //通过onShow获取本地存储,每次页面显示时都能更新数据
          onShow: function (options) {
              var that = this;
              wx.getStorage({
                  key: 'number',
                  success: function(res){
                      var number = res.data;
                      that.setData({
                          number: number
                      })
                  },
              })
          }
    

    出于严谨性,调动一下parseInt()方法,它可将字符串类型转换成数字类型。

    注意,选择页在每次加载前都应清空本地存储,不然可能存在加载完成后页面上显示的是上一次调试的数据;因此,可在onLoad中调用wx.clearStorage()。

      onLoad: function (options) {
          wx.clearStorage({
              key: 'number',
              key: 'list'
          })
      }
    

4、setInterval的使用

一直觉得拼多多的拼团提示很好玩,所以最后忍不住去首页弄一个类似的拼团模块,然后效果嘛。。。总感觉哪里怪怪的??......

其实也是不停地设置true or false来控制模块的显示与否,通过setInterval()来定时,每隔一定时间就对相应值取反,这样就能看到模块闪烁的效果了。

wxml

    <view class="invite_container" wx:if="{{show}}">
        <navigator class="invitation" animation="{{animationData}}" url="../invitation/invitation">
            <view class="invite invite_pic">
                <image src="../../images/touxiang.png"></image>
            </view>
            <view class="invite invite_content">Lesta邀请您一起剁手</view>
        </navigator>
    </view>

js

    onLoad: function() {
        var that = this;
        var animation = wx.createAnimation();
        setInterval(function () {
            var show = !that.data.show;
            that.setData({
                animationData: animation.export(),
                show: show
            })
        }, 1500)
    }

什么?你说你想一起剁手嘛??

零食拼不拼??衣服拼不拼?水果拼不拼?

好吧你点进去吧....

结束语

学习永不停歇。作为一个小白,我还有很长的路要去走,还有好多的坑要去跳,那么就在跌跌撞撞中提升吧~感谢各位小(da)伙(lao)伴将我这篇冗长文章看到最后,有哪里不足还请各位小(da)伙(lao)伴多多指教和提点。感谢!


附上我的项目地址:Lesta