点餐列表(※)

小程序点餐系统——点餐列表页(未讲解完)_微信小程序

代码

页面设计

页面分为四部分

  • 顶部:折扣信息区
  • 左侧:菜单总览
  • 右侧:菜单详细列表栏
  • 底部:购物操作

顶部:
小程序点餐系统——点餐列表页(未讲解完)_小程序_02
很简单

<!-- 折扣信息区 -->
<view class="discount">
  <text class="discount-txt"></text>满50元减10元(在线支付专享)
</view>
<view>

菜单总览
这里我们用到
scroll-view 可滚动视图区域
如图:左右都是可以上下滚动的
小程序点餐系统——点餐列表页(未讲解完)_微信小程序_03
因为左右菜单是一体,所以在两个并列的scroll-view的外面还要套上一个view标签

<view>
  <!-- 左侧菜单 -->
  <scroll-view  class="left-menu" scroll-y="true" style="height:100%">
    <view wx:for="{{listData}}" wx:key="{{index}}" class="left-menu-common {{activeIndex===index?'left-menu-selected':'left-menu-unselect'}}" data-index="{{index}}" bindtap="selectMenu">
      <view class="list-menu-name">{{item.name}}</view>
    </view>
  </scroll-view>
  <scroll-view>
  	...右侧菜单...
  </scroll-view>
</view>

listDate里的内容很多
小程序点餐系统——点餐列表页(未讲解完)_微信小程序_04

<scroll-view scroll-y="true" style="height:1200rpx;" bindscroll="scroll" scroll-into-view="{{toView}}" class="foods-wrapper" scroll-with-animation="true">
    <view class="content" id="a{{index}}" wx:for="{{listData}}" wx:key="lists">
      <view class="list-tab">{{item.name}}</view>
      <view class="content-list" wx:for="{{item.foods}}" wx:for-item="items" wx:key="list" wx:for-index="indexs">
        <view class="list-image-box">
          <image class="list-image" mode="widthFix" src="{{items.image_url}}"></image>
        </view>
        <view class="list-name-box">
          <view>{{items.name}}</view>
          <view class="list-price">
            ¥ {{items.specfoods[0].price}}.00
            <i class="iconfont icon-jiahao2fill add-icon" data-type="{{index}}" data-index="{{indexs}}" bindtap="addToCart"></i>
          </view>
        </view>
      </view>
    </view>
  </scroll-view>

底部菜单操作栏

<!-- 底部操作菜单 -->
<view class="bottom-operate-menu" wx:if="{{loading}}">
  <view class="shopping-cart">
    <view style="padding:5px;display:flex">
      <i class="iconfont icon-gouwuchefill shopping-cart-icon {{sumMonney!=0?'activity-color':'' }}" bindtap="showCartList">
        <span class="number-msg" wx:if="{{cartList.length!=0}}">{{cupNumber}}</span>
      </i>
      <view class="shopping-cart-price" wx:if="{{sumMonney==0}}">购物车是空的</view>
      <view class="shopping-cart-price" style="color:white;font-size:18px" wx:if="{{sumMonney!=0}}">¥ {{sumMonney}}.00</view>
    </view>
  </view>
  <view class="submit-btn {{sumMonney!=0?'activity-color-bg':'' }}" bindtap="goBalance">
    <view class="submit-btn-label {{sumMonney!=0?'color-white':'' }}">选好了</view>
  </view>
</view>

小程序点餐系统——点餐列表页(未讲解完)_微信小程序_05
点击购物车弹出
小程序点餐系统——点餐列表页(未讲解完)_小程序_06

<!-- 点击购物车图标(购物车部分) -->
<view class="drawer-screen" bindtap="showCartList" data-statu="close" wx:if="{{showCart}}"></view>
<view class="cartlist-content" wx:if="{{showCart}}">
  <view class="cartlist-title">
    <label class='label-title-bar'>
      <label class="lable-selected">已选商品</label>
    </label>
    <label class="lable-icon-clear" bindtap="clearCartList">
      <i class="iconfont icon-lajitong"></i>
      <label class="label-clear">清空购物车</label>
    </label>
  </view>
  <scroll-view scroll-y="true" class="{{cartList.length>5?'cart-scroll-list':''}}">
    <view class="cart-list-box" wx:for="{{cartList}}" wx:key="unique">
      <view class="listL-info">
        <view>{{item.name}}</view>
        <view class="list-info-size">{{item.detail}}</view>
      </view>
      <view class="listR-info">
        <view class="listR-info-con">
          <label class="activity-color">¥ {{item.sum}}.00</label>
          <i class="iconfont icon-jian icon-li-circle" data-index="{{index}}" bindtap="decNumber"></i>
          {{item.number}}
          <i class="iconfont icon-jiahao2fill activity-color font20" data-index="{{index}}" bindtap="addNumber"></i>
        </view>
      </view>
    </view>
  </scroll-view>
</view>

页面样式

/* 折扣信息区 */
.discount{
  width: 100%;
  height: 70rpx;
  line-height: 70rpx;
  background: #fef9e6;
  font-size: 28rpx;
  text-align: center;
  color: #999;
  z-index: 111;
}
.discount-txt{
  color:#fff;
  padding:5rpx 10rpx;
  background: red;
  margin-right: 15rpx;
}
/* 左侧菜单 */
.left-menu{
  width:160rpx;
  font-size:28rpx;
  position: absolute;
  left:0px;
  z-index: 10;
}
/* 子菜单公共样式 */
.left-menu-common{
  height: 100rpx;
  line-height: 100rpx;
  text-align: center;
}
/* 子菜单未选中样式 */
.left-menu-unselect{
  color: #6C6C6C;
  border-bottom:1px solid #E3E3E3;
  background:#F9F9F9;
}
/* 子菜单选中样式 */
.left-menu-selected{
  color: #FF9C35;
  border-left:3px solid #FF9C35;
  background:white;
}
/* 右侧菜单 */
.list-tab{
  margin-left:170rpx;
  font-size:25rpx;
  background:#F3F4F6;
  padding:2px;
  color:#FF9C35;
}
.content-list{
  margin-left:160rpx;
  display:flex;
  border-bottom: 1px solid #E3E3E3;
}
.list-image-box{
  width:160rpx;
  height:72px;
  text-align: center;
}
.list-image{
  width:108rpx;
  margin-top:16rpx;
}
.list-name-box{
  width:200px;
  font-size:30rpx;
  margin-top:20rpx;
}
.list-price{
  margin-top:20rpx;
  color:#F05A86
}
.add-icon{
  float:right;
  color:#FF9C35;
  font-size:46rpx;
}
/* 底部菜单操作 */
.bottom-operate-menu{
  z-index: 1001; 
  position: fixed;
  bottom: 0px;
  height:55px;
  width:100%;
  display: flex;
}
.shopping-cart{
  width:75%;
  background:#353535;
  height: 100%; 
}
.shopping-cart-icon{
  font-size:40px;
  color:#87888E;
  margin-left:10px;
   position: relative;
}
.activity-color{
  color:#FF9C35;
}
.submit-btn{
  height:100%;
  background:#F7F7F7;
  width:25%;
  display:flex;
}
.activity-color-bg{
  background:#FF9C35;
}
.number-msg{
  padding: 1px 7px;
  border-radius:50%;
  background:red;
  color:white;
  font-size:14px;
  position: absolute;
  text-align: center;
  top:0px;
  right:-5px;
}
.shopping-cart-price{
  color:#A9A9A9;
  display:flex;
  align-items: center;
  margin-left:10px;
  font-size:15px
}
.submit-btn-label{
  color:#A9A9A9;
  font-size:15px;
  margin:auto;
}
.color-white{
  color:white;
}
/* 弹窗 */
.drawer-screen {  
  width: 100%;  
  height: 100%;  
  position: fixed;  
  top: 0;  
  left: 0;  
  z-index: 1000;  
  background: #000;  
  opacity: 0.5;  
  overflow: hidden;  
}  
/* 购物车内容 */
.cartlist-content{  
  width: 100%; 
  overflow: hidden;  
  position: fixed;   
  z-index: 1001;
  bottom: 55px;
  max-height: 250px;  
}
.cartlist-title{
  background:#F0F0F0;
  height:30px
}
.label-title-bar{
  color:#878787;
  font-size:12px;
  border-left:4px solid #FF9C35;
  margin-left: 20px;
}
.lable-selected{
  padding:5px
}
.lable-icon-clear{
    color:#878787;
    float: right;
    margin-right: 10px;
}
.label-clear{
  color:#878787;
  font-size:12px;

}
.cart-list-box{
  background:#FFFFFF;
  display:flex;
  font-size:13px;
  border-bottom:1px #E3E3E3 solid
}
.listL-info{
  width:50%;
  padding:5px 15px;
}
.listR-info{
  width:50%;
  padding:10px;
}
.listR-info-con{
  float:right
}
.font20{
  font-size:20px
}
.list-info-size{
  font-size:10px;
  color:#B1B1B1;
}
.icon-li-circle{
  margin-left:15px;
  font-size:20px
}

.cart-scroll-list{
  height:450rpx;
}


/* 满减区域 */
.cut-bar{
  height:20px; 
  position: fixed;
  bottom:55px;
  background:#FFCD9B;
  width:100%;
  color:#FFF7EC;
  font-size:12px;
  text-align:center;
}

页面逻辑

最近时间有点紧,写的有点糙,我就不一 一 函数解释了

const fetch = require('../../utils/fetch.js')
Page({
  data: {
    activeIndex: 0,
    toView: "a0",
    cartList: [],
    currentType: 0,
    currentIndex: 0,
    sumMonney: 0, // 总价钱
    cupNumber: 0, // 购物车里商品的总数量
    showCart: false, // 是否展开购物车
    loading: false,
    containerH: '',
    heightArr: [], // 数组:查找到的所有单元的内容高度
    listData:[],
  },
  onLoad: function(options) {
    // 显示模态对话框
    wx.showLoading({
      title: "努力加载中"
    })
    // 请求数据
    fetch('food/list').then((res) => {
      wx.hideLoading();
      console.log("请求到的列表信息:");
      console.log(res.data);
      this.setData({
        listData: res.data,
        loading: true
      })
    })
  },

  // 点击左侧菜单项选择
  selectMenu: function(e) {
    let index = e.currentTarget.dataset.index
    console.log(index)
    this.setData({
      activeIndex: index,
      toView: "a" + index,
    })
  },
  // 加入购物车
  addToCart: function(e) {
    console.log(e)
    var type = e.currentTarget.dataset.type;
    var index = e.currentTarget.dataset.index;
    this.setData({
      currentType: type,
      currentIndex: index,
    });
    var a = this.data
    // 声明数组addItem
    var addItem = {
      "name": a.listData[a.currentType].foods[a.currentIndex].name,
      "price": a.listData[a.currentType].foods[a.currentIndex].specfoods[0].price,
      "number": 1,
      "sum": a.listData[a.currentType].foods[a.currentIndex].specfoods[0].price,
    }
    var sumMonney = a.sumMonney + a.listData[a.currentType].foods[a.currentIndex].specfoods[0].price;
    // 把新数组(addItem) push到 原数组cartList
    var cartList = this.data.cartList;
    cartList.push(addItem);
    this.setData({
      cartList: cartList,
      showModalStatus: false,
      sumMonney: sumMonney,
      cupNumber: a.cupNumber + 1
    });
  },
  // 展开购物车
  showCartList: function() {
    if (this.data.cartList.length != 0) {
      this.setData({
        showCart: !this.data.showCart,
      });
    }
  },
  // 购物车添加商品数量
  addNumber: function(e) {
    var index = e.currentTarget.dataset.index;
    var cartList = this.data.cartList;
    cartList[index].number++;
    var sum = this.data.sumMonney + cartList[index].price;
    cartList[index].sum += cartList[index].price;
    this.setData({
      cartList: cartList,
      sumMonney: sum,
      cupNumber: this.data.cupNumber + 1
    })
  },
  // 购物车减少商品数量
  decNumber: function(e) {
    var index = e.currentTarget.dataset.index;
    var cartList = this.data.cartList;
    var sum = this.data.sumMonney - cartList[index].price;
    cartList[index].sum -= cartList[index].price;
    cartList[index].number == 1 ? cartList.splice(index, 1) : cartList[index].number--;
    this.setData({
      cartList: cartList,
      sumMonney: sum,
      showCart: cartList.length == 0 ? false : true,
      cupNumber: this.data.cupNumber - 1
    });
  },
  // 清空购物车
  clearCartList: function() {
    this.setData({
      cartList: [],
      showCart: false,
      sumMonney: 0,
      cupNumber: 0
    });
  },
  // 点击"选好了",缓存购物车的值
  goBalance: function(e) {
    if (this.data.sumMonney == 0) {
      return
    }
    // 请求接口返回参数{error: 0(错误代码), order_id: 1}}
    var order_id = this.data.order_id
    var method = "POST"
    fetch("food/order", {id: 1,num: 1}, method).then(function(res) {
      if (res.data.error !== 0) {
        wx.showModal({
          title: '下单失败',
          content: '操作失败请重试',
        })
        return
      }
      // 请求成功后跳转到订单确认页面,把返回的order_id订单编号传过去
      wx.navigateTo({
        url: '../order/balance/balance?order_id=' + res.data.order_id
      })
    })
  }
})