前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【愚公系列】2022年11月 微信小程序-优购电商项目-商品购物车页面

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

作者头像
愚公搬代码
发布2022-11-14 17:08:35
4200
发布2022-11-14 17:08:35
举报
文章被收录于专栏:历史专栏历史专栏

文章目录

前言

1. 购物车作用

一、商品购物车页面

1.业务逻辑

2.涉及的接口数据

3. 关键技术

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

1.页面代码

2.效果

前言

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

1. 购物车作用

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

一、商品购物车页面

1.业务逻辑

渲染购物⻋数据

添加收货地址

修改商品数量

单选和全选功能

2.涉及的接口数据

获取购物⻋数据 本地存储实现

调⽤微信的收货地址

3. 关键技术

⼩程序 选择收货地址 api

⼩程序 复选框 组件

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

1.页面代码

代码语言:javascript
复制
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'
    });
      
  }
})

代码语言:javascript
复制
<!-- 收货地址 -->
<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>

代码语言:javascript
复制
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.效果

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-11-04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档