小程序外卖订单界面的示例代码


Posted in Javascript onDecember 30, 2019

1.效果界面

小程序外卖订单界面的示例代码

小程序外卖订单界面的示例代码

小程序外卖订单界面的示例代码

小程序外卖订单界面的示例代码

2.涉及功能

*左侧商品类型、右侧商品可以相互控制;
*商品列表加减及购物车商品加减icon消失、显示;
*商品每一次加减,页面视图变化(数量、价格变化、购物车置灰);

3.贴上所有代码

1.wxml   

<view class="container">
  <view class="index-cont">
   <!-- 左边类型 -->
   <view class="index-left">
    <view wx:for="{{foodsList}}" wx:key="index" class="item {{curId === 'item'+index?'on':''}}" data-id="item{{index}}" bindtap="scrollToViewFn">{{item.name}}</view>
   </view>
   <!-- 右边产品 -->
   <scroll-view class="index-right" scroll-y="{{true}}" scroll-into-view="{{initView}}" scroll-with-animation="true" bindscroll="onPageScroll">
    <view class="boxs">
     <block wx:for="{{foodsList}}" wx:key="index">
      <view class="index-title" id="item{{index}}">{{item.name}}</view>
      <view class="item" wx:for="{{item.list}}" wx:key="ind" wx:for-item="itm" wx:for-index="ind" bindtap="showGoodDetail(itm)">
       <view class="pic"><image src="{{itm.pic}}" mode="aspectFill"></image></view>
       <view class="main">
        <view class="tit">{{itm.title}}</view>
        <view class="desc">{{itm.info}}</view>
        <view class="money">¥{{itm.price}}</view>
       </view>
       <view class="box">
        <view wx:if="{{itm.num !== 0}}" class="icon" catchtap="reduceNum(index, ind, itm)"><image src="../../../static/images/reduce-icon.png" alt=""></image></view>
        <input wx:if="{{itm.num !== 0}}" type="text" disabled wx:model="{{itm.num}}"/>
        <view class="icon" catchtap="addNum(index, ind, itm)"><image src="../../../static/images/add-icon.png" alt=""></image></view>
       </view>
      </view>
     </block>
    </view>
   </scroll-view>
  </view>
  <view class="index-cart">
   <view class="left">
    <view class="cart-num" wx:if="{{cartList.length === 0}}">
     <image src="../../../static/images/cart.png"></image>
    </view>
    <view class="cart-num on" wx:else bindtap="showCartMask">
     <image src="../../../static/images/cart.png"></image>
     <text>{{totalNum}}</text>
    </view>
    <view class="cart-money">¥{{totalMoney}}</view>
   </view>
   <view class="order-btn" bindtap="submitOrder">去结算</view>
  </view>

  <!--购物车弹窗-->
  <view class="dialog" wx:if="{{isShowCartMask && cartList.length !== 0}}" bindtap="hiddenCartMak()">
   <view class="boxs" catchtap="stopMaopao()">
    <view class="title-block">
     <text>已选商品</text>
     <view class="clear" bindtap="clearCart"><image src="../../../static/images/del.png"></image>清空</view>
    </view>
    <scroll-view class="content" scroll-y="{{true}}" scroll-with-animation="true">
     <block wx:for="{{cartList}}" wx:key="index">
      <view class="item" id="{{item.view}}">
       <view class="tit">{{item.name}}</view>
       <view class="right">
        <text>¥{{item.price}}</text>
        <view class="box">
         <view class="icon" bindtap="reduceCart(index, item)"><image src="../../../static/images/reduce-icon.png" alt=""></image></view>
         <input type="text" disabled wx:model="{{item.num}}"/>
         <view class="icon" bindtap="addCart(index, item)"><image src="../../../static/images/add-icon.png" alt=""></image></view>
        </view>
       </view>
      </view>
     </block>
    </scroll-view>
   </view>
  </view>
  <!--商品详情弹窗-->
  <view class="dialog1" wx:if="{{isShowDetail}}">
   <scroll-view class="detbox" scroll-y="{{true}}" scroll-with-animation="true">
    <image class="img" src="{{goodDetail.pic}}" mode="aspectFit"></image>
    <view class="box">
     <view class="tit">{{goodDetail.title}}</view>
     <view class="money">¥{{goodDetail.price}}</view>
     <view class="desc">{{goodDetail.info}}</view>
    </view>
    <view class="close" bindtap="hideDetail"><image src="../../../static/images/close_ico.png"></image></view>
   </scroll-view>
  </view>
 </view>

2.script

createPage({
 data: {
  foodsList: [], // 商品数据
  cartList: [], // 购物车数据
  isShowCartMask: false,
  totalNum: 0,
  totalMoney: 0,
  initView: 'item0', // 根据此变量的变化,控制左侧选中状态、右侧滑动
  curId: 'item0',
  isShowDetail: false,
  goodDetail: {},
  screenWidth: 0, // 手机屏幕宽度
  heightArray: [0] // 右侧每一个类型的高度区间数组
 },
 onLoad() {
  this.getGoodsData()
 },
 methods: {
  async getGoodsData() {
   const that = this
   const res = await getGoodsInfo({})
   this.foodsList = res
   wx.getSystemInfo({
    success: (ress) => {
     that.screenWidth = ress.windowWidth
    }
   })
   this.getHeightSection()
  },
  // 设置高度区间 所有单位转化为rpx
  getHeightSection() {
   const that = this
   let hg = 0
   for (let index = 0; index < that.foodsList.length - 1; index++) {
    hg += 70 + that.foodsList[index].list.length * 212
    that.heightArray.push(hg)
   }
  },
  // 获取高度区间的下标
  getHeightIndex(arr, hg) {
   const that = this
   arr.forEach((item, index) => {
    if (hg >= item) {
     that.setData({
      curId: 'item' + index
     })
    }
   })
  },
  // 左边菜单控制右边
  scrollToViewFn(e) {
   this.setData({
    initView: e.target.dataset.id,
    curId: e.target.dataset.id
   })
  },
  // 右边滚动控制左边
  onPageScroll(e) {
   const that = this
   let scrollTop = e.detail.scrollTop * 750 / that.screenWidth
   this.getHeightIndex(that.heightArray, scrollTop)
  },
  // 商品列表的减号点击
  reduceNum(index, ind, item) {
   const that = this
   let val = 'foodsList[' + index + '].list[' + ind + '].num'
   this.setData({
    [val]: item.num - 1
   })
   // 如果商品为0,就把当前商品在购物车清除
   // 如果不为0, 就将当前商品数量减1
   if (that.foodsList[index].list[ind].num === 0) {
    that.removeAarry(that.cartList, item.id)
   } else {
    that.cartList.forEach((itm, i) => {
     if (itm.id === item.id) {
      let value = 'cartList[' + i + '].num'
      that.setData({
       [value]: itm.num - 1
      })
     }
    })
   }
   this.computed()
  },
  // 商品列表的加号点击
  addNum(index, ind, item) {
   const that = this
   let val = 'foodsList[' + index + '].list[' + ind + '].num'
   this.setData({
    [val]: item.num + 1
   })
   // 如果商品为1,就把当前商品加入购物车
   // 否则, 就将当前商品数量加1
   if (that.foodsList[index].list[ind].num === 1) {
    let val = { id: item.id, name: item.title, price: item.price, num: 1, index: index, ind: ind, pic: item.pic }
    that.cartList.push(val)
   } else {
    that.cartList.forEach((itm, i) => {
     if (itm.id === item.id) {
      let value = 'cartList[' + i + '].num'
      that.setData({
       [value]: itm.num + 1
      })
     }
    })
   }
   this.computed()
  },
  // 购物车的减号点击
  reduceCart(index, item) {
   const that = this
   let val = 'foodsList[' + item.index + '].list[' + item.ind + '].num'
   let val1 = 'cartList[' + index + '].num'
   this.setData({
    [val]: item.num - 1,
    [val1]: item.num - 1
   })
   // 如果商品为0,就把当前商品在购物车清除
   // 如果不为0, 就将当前商品数量减1
   if (that.cartList[index].num === 0) {
    that.removeAarry(that.cartList, item.id)
   }
   this.computed()
  },
  // 购物车的加号点击
  addCart(index, item) {
   const that = this
   let val = 'cartList[' + index + '].num'
   that.setData({
    [val]: item.num + 1
   })
   this.computed()
  },
  // 清空购物车
  clearCart() {
   const that = this
   wx.showModal({
    title: '提示',
    content: '清空购物车?',
    success: function (res) {
     if (res.confirm) {
      that.setData({
       cartList: []
      })
      that.foodsList.forEach((item, i) => {
       item.list.forEach((itm, j) => {
        let value = 'foodsList[' + i + '].list[' + j + '].num'
        that.setData({
         [value]: 0
        })
       })
      })
      that.computed()
     }
    }
   })
  },
  // 计算选择商品总价格和总数量
  computed() {
   const that = this
   let num = 0
   let money = 0
   that.cartList.forEach(item => {
    num += item.num
    money += parseFloat(item.price) * item.num
   })
   that.setData({
    totalNum: num,
    totalMoney: money
   })
  },
  // 将数量为0的时候,对应商品在购物车中删除
  removeAarry(arr, id) {
   arr.forEach((item, index) => {
    if (item.id === id) {
     arr.splice(index, 1)
    }
   })
   return arr
  },
  showCartMask() {
   this.isShowCartMask = !this.isShowCartMask
  },
  hiddenCartMak() {
   this.isShowCartMask = false
  },
  stopMaopao() {
  },
  showGoodDetail(item) {
   this.goodDetail = item
   this.isShowDetail = true
  },
  hideDetail() {
   this.isShowDetail = false
  },
  // 订单提交
  submitOrder() {
  }
 }
})

3.css

<style lang='scss'>
@import '../../style/base.scss';
page {
 height: 100%;
}
.container {
 height: 100vh;
 background-color: #fff;
 box-sizing: border-box;
 overflow: hidden;
  .dialog1{
   width: 100%;
   height: 100vh;
   position: fixed;
   top: 0;
   left: 0;
   background-color: rgba(0,0,0, 0.5);
   z-index: 4;
    .detbox{
     position: fixed;
     bottom: 0;
     left: 0;
     right: 0;
     background-color: #fff;
     width: 100%;
     max-height: 700rpx;
     overflow-y: auto;
     color: #333;
     border-radius: 40rpx 40rpx 0 0;
      .img{
       width: 100%;
       height: 375rpx;
       background: rgba(0,0,0,0.6);
      }
      .box{
       padding: 20rpx 30rpx 40rpx;
       box-sizing: border-box;
        .tit{
         font-size: 28rpx;
         color: #333;
         font-weight: bold;
        }
        .money{
         font-size: 26rpx;
         color: #f00;
         margin: 10rpx 0;
        }
        .desc{
         font-size: 22rpx;
         color: #666;
         line-height: 32rpx;
        }
      }
      .close{
       width: 50rpx;
       height: 50rpx;
       position: absolute;
       right: 20rpx;
       top: 20rpx;
       display: flex;
       align-items: center;
       justify-content: center;
        image{
         width: 40rpx;
         height: 40rpx;
        }
      }
    }
  }
  .dialog{
   width: 100%;
   height: 100vh;
   position: fixed;
   top: 0;
   left: 0;
   background-color: rgba(0,0,0, 0.5);
   z-index: 2;
    .boxs{
     position: fixed;
     bottom: 80rpx;
     left: 0;
     right: 0;
     z-index: 6;
     background-color: #fff;
     width: 100%;
     max-height: 600rpx;
     color: #333;
      .title-block{
       padding: 0 30rpx;
       box-sizing: border-box;
       display: flex;
       align-items: center;
       justify-content: space-between;
       height: 70rpx;
       background: #EEF0F1;
        text{
         font-size: 26rpx;
         color: #666;
        }
        .clear{
         font-size: 22rpx;
         color: #888;
         display: flex;
         align-items: center;
          image{
           width: 24rpx;
           height: 24rpx;
           margin-right: 10rpx;
          }
        }
      }
      .content{
       width: 100%;
       max-height: 530rpx;
       overflow-y: auto;
       padding-bottom: 30rpx;
       box-sizing: border-box;
        .item{
         width: 690rpx;
         height: 80rpx;
         line-height: 80rpx;
         margin: 0 auto;
         position: relative;
         display: flex;
         align-items: center;
         justify-content: space-between;
          &::after{
           position: absolute;
           width: 100%;
           height: 1rpx;
           background: #f2f2f2;
           content: '';
           bottom: 1rpx;
           left: 0;
          }
          .tit{
           width: 400rpx;
           overflow: hidden;
           text-overflow: ellipsis;
           white-space: nowrap;
           font-size: 28rpx;
           color: #333;
          }
          .right{
           display: flex;
           justify-content: flex-start;
           align-items: center;
           height: 80rpx;
            text{
             font-size: 26rpx;
             color: #f00;
            }
            .box{
             display: flex;
             justify-content: flex-start;
             align-items: center;
             flex-wrap: nowrap;
             margin-left: 20rpx;
             height: 80rpx;
              .icon{
               width: 34rpx;
               height: 34rpx;
               display: flex;
               align-items: center;
               justify-content: center;
                image{
                 width: 34rpx;
                 height: 34rpx;
                }
              }
              input{
               width: 60rpx;
               height: 34rpx;
               border: none;
               color: #333;
               text-align: center;
               font-size: 26rpx;
              }
              
            }
          }
        }
      }
    }
  }
  .index-cont{
   height: calc(100vh - 80rpx);
   display: flex;
   justify-content: space-between;
   .index-left{
    width: 160rpx;
    height: 100%;
    background: #efefef;
     .item{
      font-size: 26rpx;
      color: #333;
      border-bottom: 1rpx dashed #666;
      height: 80rpx;
      line-height: 80rpx;
      padding: 0 20rpx;
      box-sizing: border-box;
       &.on{
        background: #fff;
       }
     }
   }
   .index-right{
    width: 590rpx;
    height: 100%;
     .boxs{
      padding: 0 30rpx;
      box-sizing: border-box;
      width: 100%;
     }
     .index-title{
      height: 70rpx;
      line-height: 70rpx;
      background: #f7f7f7;
      padding-left: 30rpx;
      font-size: 26rpx;
      color: #666;
      box-sizing: border-box;
     }
     .item{
      padding: 30rpx 0;
      box-sizing: border-box;
      display: flex;
      justify-content: space-between;
      position: relative;
      height: 212rpx;
       &::after{
        position: absolute;
        top: 0rpx;
        left: 0;
        background: #ccc;
        width: 100%;
        height: 1rpx;
        content: '';
       }
       .pic{
        width: 150rpx;
        height: 150rpx;
         image{
          width: 100%;
          height: 100%;
         }
       }
       .main{
        width: 380rpx;
        padding-left: 30rpx;
        box-sizing: border-box;
         .tit{
          font-size: 26rpx;
          color: #333;
          font-weight: bold;
         }
         .desc{
          font-size: 22rpx;
          color: #999;
          line-height: 30rpx;
          margin: 5rpx 0 10rpx;
          min-height: 65rpx;
         }
         .money{
          font-size: 28rpx;
          color: #f00;
         }
       }
       .box{
        display: flex;
        justify-content: flex-start;
        align-items: center;
        flex-wrap: nowrap;
        margin-left: 10rpx;
        height: 34rpx;
        position: absolute;
        right: 0;
        bottom: 30rpx;
         .icon{
          width: 34rpx;
          height: 34rpx;
          display: flex;
          align-items: center;
          justify-content: center;
           image{
            width: 34rpx;
            height: 34rpx;
           }
         }
         input{
          width: 60rpx;
          height: 34rpx;
          border: none;
          color: #333;
          text-align: center;
          font-size: 26rpx;
         }
         
       }
     }
   }
  }
  .index-cart{
   width: 100%;
   height: 80rpx;
   display: flex;
   align-items: center;
   justify-content: flex-start;
   position: relative;
   z-index: 3;
    .left{
     width: 470rpx;
     height: 100%;
     background: #3e3a39;
     display: flex;
     align-items: center;
     justify-content: flex-start;
      .cart-num{
       width: 100rpx;
       height: 100rpx;
       background: #6E6D6C;
       position: relative;
       padding:25rpx;
       box-sizing: border-box;
       border-radius: 100%;
       top: -30rpx;
       left: 22rpx;
        &.on{
         background: $base-color;
        }
        image{
         width: 50rpx;
         height: 50rpx;
        }
        text{
         font-size: 20rpx;
         color: #fff;
         display: inline-block;
         padding: 0 9rpx;
         box-sizing: border-box;
         position: absolute;
         right: 3rpx;
         top: -3rpx;
         height: 30rpx;
         line-height: 30rpx;
         border-radius: 30rpx;
         background: #f00;
        }
      }
      .cart-money{
       color: #fff;
       font-size: 30rpx;
       margin-left: 50rpx;
      }
    }
    .order-btn{
     width: 280rpx;
     height: 100%;
     background: $base-color;
     font-size: 28rpx;
     color: #fff;
     display: flex;
     align-items: center;
     justify-content: center;
    }
  }
}

4.ps

小程序使用mpx为框架;
商品列表数据根据接口获取,测试数据可以根据mock数据测试
实际数据类型是

goodLists: [
  {
    id: 'xx',  
    name: 'xx', // 商品类型
    list: [ // 当前商品类型对应的所有商品
      {
        id: 'xx',
        title: 'xx',
        pic: 'xx',
        price: 'xx',
        detail: 'xx',
        num: '' // num是为了我方便对商品加减操作,让后端加的
      }
    ]
  }
]

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
基于jQuery实现点击同时更改两个iframe的网址
Jul 01 Javascript
jQuery的$.proxy()应用示例介绍
Apr 03 Javascript
JS折半插入排序算法实例
Dec 02 Javascript
简单谈谈JavaScript的同步与异步
Dec 31 Javascript
jquery中实现时间戳与日期相互转换
Apr 12 Javascript
AngularJs表单验证实例代码解析
Nov 29 Javascript
jQuery实现的简单动态添加、删除表格功能示例
Sep 21 jQuery
使用微信小程序开发弹出框应用实例详解
Oct 18 Javascript
es6 filter() 数组过滤方法总结
Apr 03 Javascript
Layui给switch添加响应事件的例子
Sep 03 Javascript
小程序怎样让wx.navigateBack更好用的方法实现
Nov 01 Javascript
arcgis.js控制地图地体的显示范围超出区域自动弹回(实现思路)
Jan 28 Javascript
记录微信小程序 height: calc(xx - xx);无效问题
Dec 30 #Javascript
JS三级联动代码格式实例详解
Dec 30 #Javascript
JavaScript监听触摸事件代码实例
Dec 30 #Javascript
微信公众号服务器验证Token步骤图解
Dec 30 #Javascript
微信小程序封装多张图片上传api代码实例
Dec 30 #Javascript
使用pkg打包ThinkJS项目的方法步骤
Dec 30 #Javascript
微信小程序实现一个简单swiper代码实例
Dec 30 #Javascript
You might like
php中目录,文件操作详谈
2007/03/19 PHP
解决文件名解压后乱码的问题 将文件名进行转码的代码
2012/01/10 PHP
教你如何解密 “ PHP 神盾解密工具 ”
2014/06/20 PHP
ThinkPHP实现将SESSION存入MYSQL的方法
2014/07/22 PHP
初识PHP
2014/09/28 PHP
php解析字符串里所有URL地址的方法
2015/04/03 PHP
使用XHProf查找PHP性能瓶颈的实例
2017/12/13 PHP
JavaScript 继承详解(一)
2009/07/13 Javascript
jquery imgareaselect 使用利用js与程序结合实现图片剪切
2009/07/30 Javascript
深入理解angularjs过滤器
2016/05/25 Javascript
基于JavaScript实现窗口拖动效果
2017/01/18 Javascript
node跨域请求方法小结
2017/08/25 Javascript
Vue.js最佳实践(五招助你成为vuejs大师)
2018/05/04 Javascript
js中的闭包实例展示
2018/11/01 Javascript
Vue 3.x+axios跨域方案的踩坑指南
2019/07/04 Javascript
vue计算属性+vue中class与style绑定(推荐)
2020/03/30 Javascript
详解vue中在循环中使用@mouseenter 和 @mouseleave事件闪烁问题解决方法
2020/04/07 Javascript
Vue实现背景更换颜色操作
2020/07/17 Javascript
原生js实现表格翻页和跳转
2020/09/29 Javascript
vue 单页应用和多页应用的优劣
2020/10/22 Javascript
[02:06]DOTA2英雄基础教程 暗影萨满
2013/12/16 DOTA
Python中的作用域规则详解
2015/01/30 Python
python操作redis的方法
2015/07/07 Python
python爬虫系列Selenium定向爬取虎扑篮球图片详解
2017/11/15 Python
Python实现App自动签到领取积分功能
2018/09/29 Python
python适合人工智能的理由和优势
2019/06/28 Python
Python 线性回归分析以及评价指标详解
2020/04/02 Python
python构造IP报文实例
2020/05/05 Python
python dir函数快速掌握用法技巧
2020/12/09 Python
用CSS3和table标签实现一个圆形轨迹的动画的示例代码
2019/01/17 HTML / CSS
世界上最大的巴士旅游观光公司:Big Bus Tours
2016/10/20 全球购物
澳洲的服装老品牌:SABA
2018/02/06 全球购物
放飞理想演讲稿
2014/09/09 职场文书
房屋产权证明书
2014/10/15 职场文书
初婚未育证明样本
2015/06/18 职场文书
Python爬虫之爬取哔哩哔哩热门视频排行榜
2021/04/28 Python