【愚公系列】2022年11月 微信小程序-优购电商项目-商品购物车页面

举报
愚公搬代码 发表于 2022/11/29 20:35:16 2022/11/29
【摘要】 前言网上购物车是顾客在进行网上购物时所必须使用的购物工具。它用来临时存储用户选择的商品,协助顾客从虚拟商场中选取商品、携带商品,并到虚拟的收银台结账。 1. 购物车作用电商系统中很多产品功能都是从线下已存在的产品演化到线上的,购物车也是这样。在线下商超,我们经常会使用购物车,这个时候它承担的作用有:方便运输多件商品、方便选购大件商品、方便商品统一结算。搬到线上之后,购物车被赋予了更多能力:...

前言

网上购物车是顾客在进行网上购物时所必须使用的购物工具。它用来临时存储用户选择的商品,协助顾客从虚拟商场中选取商品、携带商品,并到虚拟的收银台结账。

1. 购物车作用

电商系统中很多产品功能都是从线下已存在的产品演化到线上的,购物车也是这样。在线下商超,我们经常会使用购物车,这个时候它承担的作用有:方便运输多件商品、方便选购大件商品、方便商品统一结算。搬到线上之后,购物车被赋予了更多能力:对于用户而言,它可以保存喜欢的商品、组合计算商品价格、商品比价、促销归类、降价提醒。对平台和商家而言,可以收集购物车数据、进行购物车营销、提高客单价。

一、商品购物车页面

1.业务逻辑

  • 渲染购物⻋数据
  • 添加收货地址
  • 修改商品数量
  • 单选和全选功能

2.涉及的接口数据

  • 获取购物⻋数据 本地存储实现
  • 调⽤微信的收货地址

3. 关键技术

  • ⼩程序 选择收货地址 api
  • ⼩程序 复选框 组件

二、商品购物车页面相关代码

1.页面代码

import { getSetting, chooseAddress, openSetting, showModal ,showToast} from "../../utils/asyncWx.js";

Page({
  data: {
    address: {},
    cart: [],
    allChecked: false,
    totalPrice: 0,
    totalNum: 0
  },
  onShow() {
    // 1 获取缓存中的收货地址信息
    const address = wx.getStorageSync("address");
    // 1 获取缓存中的购物车数据
    const cart = wx.getStorageSync("cart") || [];

    this.setData({ address });
    this.setCart(cart);

  },
  // 点击 收货地址
  async handleChooseAddress() {
    try {
      // 1 获取 权限状态
      const res1 = await getSetting();
      const scopeAddress = res1.authSetting["scope.address"];
      // 2 判断 权限状态
      if (scopeAddress === false) {
        await openSetting();
      }
      // 4 调用获取收货地址的 api
      let address = await chooseAddress();
      address.all = address.provinceName + address.cityName + address.countyName + address.detailInfo;

      // 5 存入到缓存中
      wx.setStorageSync("address", address);

    } catch (error) {
      console.log(error);
    }
  },
  // 商品的选中
  handeItemChange(e) {
    // 1 获取被修改的商品的id
    const goods_id = e.currentTarget.dataset.id;
    // 2 获取购物车数组 
    let { cart } = this.data;
    // 3 找到被修改的商品对象
    let index = cart.findIndex(v => v.goods_id === goods_id);
    // 4 选中状态取反
    cart[index].checked = !cart[index].checked;

    this.setCart(cart);

  },
  // 设置购物车状态同时 重新计算 底部工具栏的数据 全选 总价格 购买的数量
  setCart(cart) {
    let allChecked = true;
    // 1 总价格 总数量
    let totalPrice = 0;
    let totalNum = 0;
    cart.forEach(v => {
      if (v.checked) {
        totalPrice += v.num * v.goods_price;
        totalNum += v.num;
      } else {
        allChecked = false;
      }
    })
    // 判断数组是否为空
    allChecked = cart.length != 0 ? allChecked : false;
    this.setData({
      cart,
      totalPrice, totalNum, allChecked
    });
    wx.setStorageSync("cart", cart);
  },
  // 商品全选功能
  handleItemAllCheck() {
    // 1 获取data中的数据
    let { cart, allChecked } = this.data;
    // 2 修改值
    allChecked = !allChecked;
    // 3 循环修改cart数组 中的商品选中状态
    cart.forEach(v => v.checked = allChecked);
    // 4 把修改后的值 填充回data或者缓存中
    this.setCart(cart);
  },
  // 商品数量的编辑功能
  async handleItemNumEdit(e) {


    // 1 获取传递过来的参数 
    const { operation, id } = e.currentTarget.dataset;
    // 2 获取购物车数组
    let { cart } = this.data;
    // 3 找到需要修改的商品的索引
    const index = cart.findIndex(v => v.goods_id === id);
    // 4 判断是否要执行删除
    if (cart[index].num === 1 && operation === -1) {
      // 4.1 弹窗提示
      const res = await showModal({ content: "您是否要删除?" });
      if (res.confirm) {
        cart.splice(index, 1);
        this.setCart(cart);
      }
    } else {
      // 4  进行修改数量
      cart[index].num += operation;
      // 5 设置回缓存和data中
      this.setCart(cart);
    }
  },
  // 点击 结算 
  async handlePay(){
    // 1 判断收货地址
    const {address,totalNum}=this.data;
    if(!address.userName){
      await showToast({title:"您还没有选择收货地址"});
      return;
    }
    // 2 判断用户有没有选购商品
    if(totalNum===0){
      await showToast({title:"您还没有选购商品"});
      return ;
    }
    // 3 跳转到 支付页面
    wx.navigateTo({
      url: '/pages/pay/index'
    });
      
  }
})
<!-- 收货地址 -->
<view class="revice_address_row">
  <!-- 当收货地址 不存在 按钮显示  对象 空对象 bool类型也是true  -->
  <view class="address_btn" wx:if="{{!address.userName}}"  >
    <button bindtap="handleChooseAddress" type="primary"  plain  >获取收货地址</button>
  </view>
  <!-- 当收货地址 存在 详细信息就显示 -->
  <view wx:else  class="user_info_row" >
    <view class="user_info">
      <view>{{address.userName}}</view>
      <view>{{address.all}}</view>
    </view>
    <view class="user_phone">{{address.telNumber}}</view>
  </view>
</view>

<!-- 购物车内容 -->
<view class="cart_content">
  <view class="cart_title">购物车</view>
  <view class="cart_main">
    <!-- 当cart数组 长度不为0 显示 商品信息 -->
    <block wx:if="{{cart.length!==0}}">
        <view class="cart_item"
      wx:for="{{cart}}"
      wx:key="goods_id"
      >
          <!-- 复选框 -->
          <view class="cart_chk_wrap">
            <checkbox-group data-id="{{item.goods_id}}" bindchange="handeItemChange">
              <checkbox checked="{{item.checked}}"></checkbox>
            </checkbox-group>
          </view>
          <!-- 商品图片 -->
          <navigator class="cart_img_wrap">
          <image mode="widthFix" src="{{item.goods_small_logo}}" ></image>
          </navigator>
          <!-- 商品信息 -->
          <view class="cart_info_wrap">
            <view class="goods_name">{{item.goods_name}}</view>
            <view class="goods_price_wrap">
              <view class="goods_price">{{item.goods_price}}</view>
              <view class="cart_num_tool">
                <view bindtap="handleItemNumEdit" data-id="{{item.goods_id}}" data-operation="{{-1}}"  class="num_edit">-</view>
                <view class="goods_num">{{item.num}}</view>
                <view bindtap="handleItemNumEdit" data-id="{{item.goods_id}}" data-operation="{{1}}"  class="num_edit">+</view>
              </view>
            </view>
          </view>
        </view>
    </block>
    <block wx:else>
      <image mode="widthFix" src="http://hbimg.b0.upaiyun.com/e1b1467beea0a9c7d6a56b32bac6d7e5dcd914f7c3e6-YTwUd6_fw658" ></image>
    </block>
  </view>
</view>

<!-- 底部工具栏 -->
<view class="footer_tool">
  <!-- 全选 -->
  <view class="all_chk_wrap">
    <checkbox-group bindchange="handleItemAllCheck">
      <checkbox checked="{{allChecked}}">全选</checkbox>
    </checkbox-group>
  </view>
  <!-- 总价格 -->
  <view class="total_price_wrap">
    <view class="total_price">
      合计: <text class="total_price_text">{{totalPrice}}</text>
    </view>
    <view>包含运费</view>
  </view>
  <!-- 结算 -->
  <view class="order_pay_wrap" bindtap="handlePay" >
    结算({{totalNum}})
  </view>
</view>
page {
  padding-bottom: 90rpx;
}
.revice_address_row .address_btn {
  padding: 20rpx;
}
.revice_address_row .address_btn button {
  width: 60%;
}
.revice_address_row .user_info_row {
  display: flex;
  padding: 20rpx;
}
.revice_address_row .user_info_row .user_info {
  flex: 5;
}
.revice_address_row .user_info_row .user_phone {
  flex: 3;
  text-align: right;
}
.cart_content .cart_title {
  padding: 20rpx;
  font-size: 36rpx;
  color: var(--themeColor);
  border-top: 1rpx solid currentColor;
  border-bottom: 1rpx solid currentColor;
}
.cart_content .cart_main .cart_item {
  display: flex;
  padding: 10rpx;
  border-bottom: 1rpx solid #ccc;
}
.cart_content .cart_main .cart_item .cart_chk_wrap {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
}
.cart_content .cart_main .cart_item .cart_img_wrap {
  flex: 2;
  display: flex;
  justify-content: center;
  align-items: center;
}
.cart_content .cart_main .cart_item .cart_img_wrap image {
  width: 80%;
}
.cart_content .cart_main .cart_item .cart_info_wrap {
  flex: 4;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
}
.cart_content .cart_main .cart_item .cart_info_wrap .goods_name {
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  color: #666;
}
.cart_content .cart_main .cart_item .cart_info_wrap .goods_price_wrap {
  display: flex;
  justify-content: space-between;
}
.cart_content .cart_main .cart_item .cart_info_wrap .goods_price_wrap .goods_price {
  color: var(--themeColor);
  font-size: 34rpx;
}
.cart_content .cart_main .cart_item .cart_info_wrap .goods_price_wrap .cart_num_tool {
  display: flex;
}
.cart_content .cart_main .cart_item .cart_info_wrap .goods_price_wrap .cart_num_tool .num_edit {
  width: 55rpx;
  height: 55rpx;
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1rpx solid #ccc;
}
.cart_content .cart_main .cart_item .cart_info_wrap .goods_price_wrap .cart_num_tool .goods_num {
  width: 55rpx;
  height: 55rpx;
  display: flex;
  justify-content: center;
  align-items: center;
}
.footer_tool {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 90rpx;
  background-color: #fff;
  display: flex;
  border-top: 1rpx solid #ccc;
}
.footer_tool .all_chk_wrap {
  flex: 2;
  display: flex;
  justify-content: center;
  align-items: center;
}
.footer_tool .total_price_wrap {
  flex: 5;
  padding-right: 15rpx;
  text-align: right;
}
.footer_tool .total_price_wrap .total_price .total_price_text {
  color: var(--themeColor);
  font-size: 34rpx;
  font-weight: 600;
}
.footer_tool .order_pay_wrap {
  flex: 3;
  background-color: var(--themeColor);
  color: #fff;
  font-size: 32rpx;
  font-weight: 600;
  display: flex;
  justify-content: center;
  align-items: center;
}

2.效果

在这里插入图片描述

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。