微信小程序-购物车详情

396 阅读2分钟

微信小程序记录 - 购物车页面

首先浏览整个页面

image.png

组成部分

整个页面分成三个部分:

  • 1、是搜索部分
  • 2、是左边第一层分类
  • 3、是右边的小分类和产品列表

父组件部分

<view class="main">
    <!-- 搜索和筛选 -->
    <view class="enum-wrap">
        <van-search class="search" value="{{ keyword }}" use-action-slot="true" bind:search="onSearch"
            bind:change="searchChangeHandle" placeholder="请输入产品名称">
            <view slot="action" bind:tap="searchHandle">搜索</view>
        </van-search>
    </view>
     <!-- 左边的大分类 -->
    <view class="content">
        <view class="classify-wrap" wx:if="option.length">
            <view wx:for="{{option}}" wx:key="id" class="classfiy">
                <view bindtap="clickHandle" data-id="{{item.id}}" data-note1="{{item.note1}}"
                    data-note2="{{item.note2}}" class="{{curIndex===item.id?'active':''}}">
                    {{item.name}}</view>
            </view>
        </view>
        <view class="product">
            <!-- 二级分类 -->
            <scroll-check enumns='{{xiaolei}}' bind:click="clickMe" />
            <!-- 产品列表 -->
            <view class="product-content card" wx:for="{{productList}}" wx:key='id'>
                <product-card bind:onChange="onChange" productdetail="{{item}}" bind:getVal='getVal' />
            </view>
            <!-- 购物车详情 -->
            <view class="shop-car ">
                <van-icon bind:click="shoppingDetailHandle" size="70rpx" color="#fff" name="cart-o" />
            </view>
            <van-notify id="van-notify" />
        </view>
    </view>
</view>
const app = getApp()
Page({
  /**
   * 页面的初始数据
   */
  data: {
    option: [],
    xiaolei: [],
    value1: 0,
    value: 0,
    productList: [],
    cargoList: [],
    keyword: '',
    curIndex: 0,
  },
  // 点击小类触发
  clickMe(e) {
    this.getOrderList(e.detail)
  },
  searchHandle() {
    this.getOrderList(e.detail)
  },
  searchChangeHandle(e) {
   this.getOrderList(e.detail)
    this.setData({
      keyword: e.detail.keyword
    })
  },
  onSearch(e) {
    console.log(e);
  },
  // 绑定查看购物车详情
  shoppingDetailHandle(e) {
    
  },
  clickHandle(e) {
    const id = e.currentTarget.dataset.id
    let args = e.currentTarget.dataset
    this.getEnums(args)
    this.setData({
      curIndex: id
    })
  },
// 重点部分,这边因为需要在每次输入完只有取到箱瓶的数量,并把它们合并成一个对象插入到数组中,最终数组作为参数传参给后端
  getVal(e) {
    let arr = this.data.cargoList; // 初始数组
    let data = e.detail //对象{}
    let length = arr.length
    if (!length) {
      arr.push(data)
    } else {
      arr.map(item => {
        if (item.id === data.id) {
          const args = Object.assign({}, item, data)
          let newArr = arr.filter(item => item.id !== data.id)
          arr = [...newArr, args]
        } else {
          arr.push(data)
        }
      })
    }
  //  [{ping:0,xiang:0,Id:0}]
    this.setData({
      cargoList: arr
    })
  },
  getEnums(args) {
   // 得到枚举(大小分类)
   this.getOrderList(args)
  },
  getOrderList(args) {
    // 拿到订单列表
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    const that = this;
    that.getEnums();
  },
})
.main {
    background: #fff;
    width: 750rpx;
    height: 100vh;

    // 分类
    .content {
        position: relative;
        height: 89%;

        .classify-wrap {
            position: absolute;
            top: 0;
            bottom: -12px;
            left: 0;
            width: 200rpx;
            background: #f9f9f9;
            overflow-y: auto;

            .classfiy {
                height: 100rpx;
                line-height: 100rpx;
                text-align: center;
            }

            .active {
                background-color: #fff;
                color: @green;
            }
        }

        // 产品
        .product {
            overflow-y: auto;
            margin-left: 200rpx;
            padding: 0 12rpx;

            .product-content {
                margin-bottom: 16rpx;
            }

            // 购物车
            .shop-car {
                position: fixed;
                right: 20px;
                bottom: 100rpx;
                width: 100rpx;
                height: 100rpx;
                border-radius: 100%;
                border: 1px solid @green;
                background: @green;
                display: flex;
                align-items: center;
                justify-content: center;
                z-index: 2
            }
        }
    }
}

@import "../../../styles/common.less"; // 这边用到了一些颜色,可以自行更换

子组件部分只有两个一个是产品列表,一个是小分类

首先是产品列表card

<view class="product-detail">
    <view class="marginbt4">{{productdetail.id}}</view>
    <view class="marginbt4">产品:{{productdetail.name}}</view>
    <view class="fontSize12 marginbt4">库存:{{productdetail.inventory}}/{{productdetail.uom}}</view>
    <view class="fontSize12 marginbt4">单价:{{productdetail.unitPrice}}/{{productdetail.uom}}</view>
    <view class="product-btn">
        <view class="wrap">
            <view class="input-wrap">
                <input type="number" bindinput="inputEdit" data-name="curPackqty" data-id="{{productdetail.id}}"
                    type="text" value="{{curPackqty}}" placeholder="0"
                    style="padding:0;width:80rpx;font-size:24rpx;text-align:center" />
                <text>箱</text>
            </view>
            <view class="input-wrap">
                <input type="number" bindinput="inputEdit" data-id="{{productdetail.id}}" data-name="curQty" type="text"
                    placeholder="0" value="{{curQty}}"
                    style="padding:0;width:80rpx;font-size:24rpx;text-align:center" />
                <text>瓶</text>
            </view>
        </view>
    </view>
</view>
// components/productCard/productCard.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    productdetail: {
      type: Object,
      default: {},
    },
  },

  /**
   * 组件的初始数据
   */
  data: {
    curPackqty: null, // 箱
    curQty: null, // 瓶
    activity: false
  },
  //  在组件实例进入页面节点树时执行
  attached() {
    this.setData({
      curPackqty: this.properties.productdetail.value,
      curQty: this.properties.productdetail.volume
    })
  },

  /**
   * 组件的方法列表
   */
  methods: {
    // 小程序双向数据绑定
    inputEdit(e) {
      const dataSet = e.currentTarget.dataset;
      const value = e.detail.value; // 值
      const name = dataSet.name;
      this.data[name] = value;
      this.setData({
        name: this.data[name]
      })
      this.triggerEvent('getVal', {
        [dataSet.name]: this.data[name],
        id: dataSet.id,
      })
    },
  }
})
.product-detail {
    margin-bottom: 8px;

    .fontSize12 {
        font-size: 12px;
        color: #999
    }

    .marginbt4 {
        margin-bottom: 4px;
    }

    .product-btn {
        font-size: 24rpx;
        display: flex;
        justify-content: flex-end;
        padding: 4px;

        .wrap {
            border: 1px solid #eee;
            border-radius: 4px;
            display: flex;

            .input-wrap {
                display: flex;
                justify-content: center;
                align-items: center;
                margin-right: 8px;
                padding: 0 8px;

            }
        }
    }
}

接下来是小分类

<view class="enum-wrap-small">
    <view wx:for="{{enumns}}" wx:key="id">
        <view bindtap="clickHandle" data-operation="{{item.id}}" class="tags {{curIndex===item.id?'active':''}}">
            {{item.name}}
        </view>
    </view>
</view>
// components/scrollCheck/scrollCheck.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    enumns: {
      type: Array, //要接收的数据类型
      value: 0 //默认值(可选)
    }
  },

  /**
   * 组件的初始数据
   */
  data: {

  },

  /**
   * 组件的方法列表
   */
  methods: {
    clickHandle: function (e) {
      const that = this;
      const id = e.currentTarget.dataset.operation
      that.triggerEvent("click", {
        id
      })
      that.setData({
        curIndex: id
      })
    }
  }
})
// 小分类
.enum-wrap-small {
    display: flex;
    margin: 4px 0;
    overflow-x: auto;

    &::-webkit-scrollbar {
        width: 0 !important;
        height: 0 !important;
    }

    .tags {
        border: 1px solid #eee;
        padding: 2px;
        margin: 4px 0;
        width: 160rpx;
        margin-right: 8px;
        border-radius: 4px;
        font-size: 12px;
        color: #999;
        overflow: hidden;
        text-align: center;
    }

    .active {
        color: #1989fa;
        border: 1px solid #1989fa;
    }
}