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


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 相关文章推荐
javascript arguments 传递给函数的隐含参数
Aug 21 Javascript
JS实现常见的TAB、弹出层效果(TAB标签,斑马线,遮罩层等)
Oct 08 Javascript
jQuery实现简单隔行变色的方法
Feb 20 Javascript
jQuery实现查找链接文字替换属性的方法
Jun 27 Javascript
浅谈window.onbeforeunload() 事件调用ajax
Jun 29 Javascript
jquery 抽奖小程序实现代码
Oct 12 Javascript
微信小程序 教程之WXML
Oct 18 Javascript
网页瀑布流布局jQuery实现代码
Oct 21 Javascript
Angular5.1新功能分享
Dec 21 Javascript
浅谈Koa2框架利用CORS完成跨域ajax请求
Mar 06 Javascript
Vue路由切换页面不更新问题解决方案
Jul 10 Javascript
vue+springboot+element+vue-resource实现文件上传教程
Oct 21 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模板类代码
2008/09/07 PHP
PHP 接入支付宝即时到账功能
2016/09/18 PHP
PHP递归实现文件夹的复制、删除、查看大小操作示例
2017/08/11 PHP
Laravel框架实现redis集群的方法分析
2017/09/14 PHP
javascript 基础篇4 window对象,DOM
2012/03/14 Javascript
JQuery触发radio或checkbox的change事件
2012/12/18 Javascript
解决extjs grid 不随窗口大小自适应的改变问题
2014/01/26 Javascript
JavaScript中的迭代器和生成器详解
2014/10/29 Javascript
javascript原型模式用法实例详解
2015/06/04 Javascript
简单谈谈JavaScript的同步与异步
2015/12/31 Javascript
js每隔两秒输出数组中的一项(实例)
2017/05/28 Javascript
详解如何在vue项目中使用lodop打印插件
2018/09/27 Javascript
微信公众号平台接口开发 获取微信服务器IP地址方法解析
2019/08/14 Javascript
vue实现输入框自动跳转功能
2020/05/20 Javascript
Django中模版的子目录与include标签的使用方法
2015/07/16 Python
python用模块zlib压缩与解压字符串和文件的方法
2016/12/16 Python
解决python文件字符串转列表时遇到空行的问题
2017/07/09 Python
对python中的xlsxwriter库简单分析
2018/05/04 Python
解决Pycharm运行时找不到文件的问题
2018/10/29 Python
Python实现多进程的四种方式
2019/02/22 Python
numpy.linspace函数具体使用详解
2019/05/27 Python
centos 安装Python3 及对应的pip教程详解
2019/06/28 Python
python傅里叶变换FFT绘制频谱图
2019/07/19 Python
Python 实现加密过的PDF文件转WORD格式
2020/02/04 Python
解决pyCharm中 module 调用失败的问题
2020/02/12 Python
python神经网络编程实现手写数字识别
2020/05/27 Python
pyCharm 设置调试输出窗口中文显示方式(字符码转换)
2020/06/09 Python
用python给csv里的数据排序的具体代码
2020/07/17 Python
canvas生成带二维码海报的踩坑记录
2019/09/11 HTML / CSS
网络、C以及其他硬件方面的面试题
2016/08/23 面试题
动态密码技术
2012/10/18 面试题
网上卖盒饭创业计划书范文
2014/02/07 职场文书
六一儿童节活动总结
2014/08/27 职场文书
情况说明书怎么写
2015/10/08 职场文书
聊聊基于pytorch实现Resnet对本地数据集的训练问题
2022/03/25 Python
为什么MySQL8新特性会修改自增主键属性
2022/04/18 MySQL