欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-03-08 14:13:33
1.效果界面 2.涉及功能 *左侧商品类型、右侧商品可以相互控制; *商品列表加减及购物车商品加减icon消失、显示; *商品每一次加减,页面视...

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是为了我方便对商品加减操作,让后端加的
      }
    ]
  }
]

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