开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
上一篇写了商品详情页面实现、首页轮播图和热卖推荐点击跳转详情页功能 ,这一篇开始写商品的购物车页面实现。
购物车页面实现
1.商品加入购物车逻辑实现
思路:当用户点击加入购物车时,利用wx.setStorageSync和wx.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.测试
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)
},
})
},
- 生命周期函数--监听页面显示 onShow() 方法
/**
* 生命周期函数--监听页面显示
*/
onShow() {
// 1.获取缓存中的收货地址信息
const address=wx.getStorageSync('address');
// 2.给data赋值
this.setData({
address
})
},
5.测试
点击获取收货地址 拿到用户收货地址-选择-确定
当收货地址 存在 详细信息就显示
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);
}
未加入购物车时:
加入购车后
4.购物车底部工具栏实现
1.index.wxml页面增加
<!-- 底部工具栏 -->
<view class="footer_tool">
<!--全选-->
<view class="all_chk_wrap">
<checkbox-group bindchange="handleItemAllCheck">
<checkbox checked="{{allChecked}}" >
<text decode="{{true}}"> 全选</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选中属性
2.定义allChecked全选属性
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);
}
},
测试:
7.商品详情立即购买逻辑实现
1.优化详情页面
<view class="tool_item btn_buy" bindtap="handleBuy">
立即购买
</view>
2.增加立即购买逻辑
// 点击 立即购买
handleBuy(){
this.setCartAdd();
wx.switchTab({
url: '/pages/cart/index',
})
},
至此购物车页面实现完成
下一篇:
支付页面实现