微信小程序实战(购物车页面实现)

2,465 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

上一篇写了商品详情页面实现、首页轮播图和热卖推荐点击跳转详情页功能 ,这一篇开始写商品的购物车页面实现。

购物车页面实现

1.商品加入购物车逻辑实现

思路:当用户点击加入购物车时,利用wx.setStorageSyncwx.getStorageSync方法将产品信息存入缓存

1.修改产品详情页面js逻辑

  productInfo:{//创建产品信息数组

  },

  // 获取产品信息
  async getProductDetail(id){
    const result=await requestUtil({url: "/v1/miniProgram/tProductSwiperImage/detail",data:{id}});
    this.productInfo=result.data; //获取产品详情时存储productInfo
    this.setData({
      productObj:result.data
    })
  },

2.页面增加加入购物车按钮逻辑handleCartAdd

  <view class="tool_item btn_cart" bindtap="handleCartAdd">
    加入购物车
  </view>

3.按钮逻辑handleCartAdd 点击加入购物车调用setCartAdd()方法,并提示加入成功

  // 点击 加入购物车
  handleCartAdd() {
    this.setCartAdd();
    // 弹窗提示
    wx.showToast({
      title: '加入成功',
      icon:'success',
      mask:true
    })
  },

4.setCartAdd()方法

// 加入购物车
  setCartAdd(){
    // 获取缓存中的购物车 数组格式
    let cart=wx.getStorageSync('cart')||[];
    // 判断商品对象中是否存在于购物车数组中
    let index=cart.findIndex(v=>v.id===this.productInfo.id);
    if(index===-1){  // 不存在
      this.productInfo.num=1;
      this.productInfo.checked=true;
      cart.push(this.productInfo);
    }else{  // 已经存在
      cart[index].num++;
    }
    wx.setStorageSync('cart', cart); // 把购物车添加到缓存中
  },

5.测试

image.png

2.购物车页面收货地址实现

1.使用接口wx.chooseAddress

额,真实环境要声明调用已经申请开通接口调用权限了,这个后面真实环境碰到了再说吧。

 2022  7  14 日后发布的小程序,若使用该接口,需要在 app.json 中进行声明,否则将无
法正常使用该接口,2022年7月14日前发布的小程序不受影响。

具体规则见公告

2.收货地址页面实现index.wxml 当缓存中address 不存在时显示获取收货地址 ,存在时展示收货地址信息。获取收获地址及更换地址调用handleChooseAddress()方法

<!--pages/cart/index.wxml-->
<!-- 收货地址 开始 -->
<view class="revice_address_row">
  <!-- 当收货地址 不存在 按钮显示 -->
  <view class="address_btn" wx:if="{{!address}}">
    <button bindtap="handleChooseAddress" type="warn" plain>获取收货地址</button>
  </view>
  <!-- 当收货地址 存在 详细信息就显示 -->
  <view wx:else class="user_info_row">
    <view class="user_info">
      <view>收货人:{{address.userName}},{{address.telNumber}}</view>
      <view>{{address.provinceName+address.cityName+address.countyName+address.detailInfo}}</view>
    </view>
    <view class="change_address">
      <button  bindtap="handleChooseAddress" size="mini" type="default" plain>更换地址</button>
    </view>
  </view>
</view>
<!-- 收货地址 结束 -->

3.handleChooseAddress()方法 使用wx.chooseAddress方法获取用户地址(模拟器环境只有一个默认的),存储result信息 key为address

  // 点击 获取收货地址
  handleChooseAddress(){
    wx.chooseAddress({
      success: (result) => {
        wx.setStorageSync('address', result)
      },
    })
  },
  1. 生命周期函数--监听页面显示 onShow() 方法
  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
    // 1.获取缓存中的收货地址信息
    const address=wx.getStorageSync('address');
    // 2.给data赋值
    this.setData({
      address
    })
  },

5.测试

image.png

点击获取收货地址 拿到用户收货地址-选择-确定

image.png

当收货地址 存在 详细信息就显示

image.png

3.购物车商品列表显示实现

1.在第一步中已经将购物车的数据存储到了缓存中,因此在购物车页面 onShow() 方法方法中获取

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
    // 1.获取缓存中的收货地址信息
    const address=wx.getStorageSync('address');
    // 2.获取缓冲中的购物车数据
    const cart=wx.getStorageSync('cart')||[];
    // 给data赋值
    this.setData({
      address
    })
    this.setCart(cart);
  },

2.页面展示 根据cart.length判断缓存中是否有加入购物车的商品,如果有则展示加入购物车的商品,如果没有则展示empty.gif动图。

页面:


<!-- 购物车清单 开始 -->
<view class="cart_content">
  <view class="cart_main">
    <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.id}}" bindchange="handleItemChange">
            <checkbox checked="{{item.checked}}"></checkbox>
          </checkbox-group>
        </view>
        <!-- 商品图片 -->
        <navigator class="cart_img_wrap" url="/pages/product_detail/index?id={{item.id}}">
          <image mode="widthFix" src="{{item.propic}}"></image>
        </navigator>
        <!-- 商品信息 -->
        <view class="cart_info_warp">
          <navigator url="/pages/product_detail/index?id={{item.id}}">
            <view class="goods_name">{{item.name}}</view>
          </navigator>
          <view class="goods_price_wrap">
            <view class="goods_price"> ¥{{item.price}}</view>
            <view class="cart_num_tool">
              <view class="num_edit" bindtap="handleItemNumEdit" data-id="{{item.id}}" data-operation="{{-1}}"></view>
              <view class="goods_num">{{item.num}}</view>
              <view class="num_edit"  bindtap="handleItemNumEdit" data-id="{{item.id}}" data-operation="{{1}}">+</view>
            </view>
          </view>
        </view>
      </view>
    </block>
    <block wx:else>
    <image mode="widthFix" src="/icons/empty.gif"></image>
   </block>
  </view>
</view>
<!-- 购物车清单 结束 -->

样式:

/**index.less**/
.index_swiper swiper {
  width: 750rpx;
  height: 375rpx;
}
.index_swiper swiper swiper-item image {
  width: 100%;
}
.index_bigType {
  padding-top: 20rpx;
  background-color: #F7F7F7;
}
.index_bigType .bigTypeRow {
  display: flex;
}
.index_bigType .bigTypeRow navigator {
  flex: 1;
}
.index_bigType .bigTypeRow navigator image {
  width: 150rpx;
}
.index_hot_product .product_title {
  font-size: 32rpx;
  background-color: #E0E0E0;
  font-weight: 600;
  padding: 20rpx;
  color: var(--themeColor);
}
.index_hot_product .list {
  display: flex;
  flex-wrap: wrap;
}
.index_hot_product .list .product_detail {
  margin: 15rpx;
  width: 46%;
  text-align: center;
}
.index_hot_product .list .product_detail navigator image {
  width: 100%;
  background-color: #F5F5F5;
}
.index_hot_product .list .product_detail navigator .product_name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.index_hot_product .list .product_detail navigator .product_price {
  color: var(--themeColor);
}

未加入购物车时:

image.png

加入购车后

image.png

4.购物车底部工具栏实现

1.index.wxml页面增加


<!-- 底部工具栏 -->
<view class="footer_tool">
  <!--全选-->
  <view class="all_chk_wrap">
    <checkbox-group bindchange="handleItemAllCheck">
      <checkbox checked="{{allChecked}}" >
        <text  decode="{{true}}">&nbsp;&nbsp;全选</text></checkbox>
    </checkbox-group>
  </view>

  <!-- 总价格 -->
  <view class="total_price_wrap">
    <view class="total_price">
     合计:<text class="total_price_text">¥{{totalPrice}}</text>
    </view>
  </view>

  <!-- 结算 -->
  <view class="order_pay_wrap" bindtap="handlePay" >
    结算({{totalNum}})
  </view>
</view>

5.购物车底部工具栏全选、总价、总数量实现

1.购物车商品加一个checked选中属性

image.png

2.定义allChecked全选属性

image.png

3.商品多选功能handleItemAllCheck

    // 商品全选功能
    handleItemAllCheck(){
      // 获取data中的数据
      let {cart,allChecked}=this.data;
      // 修改值
      allChecked=!allChecked;
      // 循环修改cart数组中的商品修改状态
      cart.forEach(v=>v.checked=allChecked);
      // 修改后的值 填充回data以及缓存中
      this.setCart(cart);
    },

4.总价和总数量实现,定义totalPrice和totalNum

  /**
   * 页面的初始数据
   */
  data: {
    address:{},
    cart:[],
    baseUrl:'',
    allChecked:false,
    totalPrice:0,
    totalNum:0
  },

5.设置购物车公共处理类-setCart封装


  // 设置购物车状态 同时 重新计算 底部工具栏的数据 全选 总价格 购买的数量
  setCart(cart) {
    let allChecked = true;
    // 1 总价格 总数量
    let totalPrice = 0;
    let totalNum = 0;
    cart.forEach(v => {
      if (v.checked) {
        totalPrice += v.num * v.price;
        totalNum += v.num;
      } else {
        allChecked = false;
      }
    })
    // 判断cart数组是否位空
    allChecked = cart.length != 0 ? allChecked : false;
    // 2 给data赋值
    this.setData({
      cart,
      allChecked,
      totalPrice,
      totalNum
    })
    wx.setStorageSync('cart', cart);
  },

6. 购物车商品数量编辑实现

1.页面绑定handleItemNumEdit事件,带上id和operation参数

            <view class="cart_num_tool">
              <view class="num_edit" bindtap="handleItemNumEdit" data-id="{{item.id}}" data-operation="{{-1}}">–</view>
              <view class="goods_num">{{item.num}}</view>
              <view class="num_edit"  bindtap="handleItemNumEdit" data-id="{{item.id}}" data-operation="{{1}}">+</view>
            </view>

2.handleItemNumEdit事件,购物车商品数量为0判断是否删除

 // 商品数量的编辑功能
  handleItemNumEdit(e){
  
    const {operation,id}=e.currentTarget.dataset;
    console.log(operation,id);
    let {cart}=this.data;
    const index=cart.findIndex(v=>v.id===id);
    if(cart[index].num===1 && operation===-1){
      wx.showModal({
        title:'系统提示',
        content:'您是否要删除?',
        cancelColor: 'cancelColor',
        success:(res)=>{
          if(res.confirm){
            cart.splice(index,1);
            this.setCart(cart);
          }
        }
      })
    }else{
      cart[index].num+=operation;
      this.setCart(cart);
    }
  },

测试:

image.png

7.商品详情立即购买逻辑实现

1.优化详情页面

  <view class="tool_item btn_buy" bindtap="handleBuy">
    立即购买
  </view>

2.增加立即购买逻辑


  // 点击 立即购买
  handleBuy(){
    this.setCartAdd();
    wx.switchTab({
      url: '/pages/cart/index',
    })
  },

至此购物车页面实现完成

下一篇:

支付页面实现