购物车页面布局
引入 WeUI:
{"usingComponents": {"mp-cells": "weui-miniprogram/cells/cells","mp-cell": "weui-miniprogram/cell/cell","mp-slideview": "weui-miniprogram/slideview/slideview"},"navigationBarTitleText": "购物车"}
<!--pages/shopcar/shopcar.wxml--><mp-cells ext-class="my-cells" title="购物车商品信息" footer="左滑可以删除" wx:if="{{cartList.length}}"><!-- 左滑删除功能 --><mp-slideview buttons="{{slideButtons}}" bindbuttontap="slideButtonTap" wx:for="{{cartList}}" wx:key="index" data-id="{{item.id}}"><mp-cell><!-- 使用slot插槽的footer,固定具体右侧的数量增减功能 --><view slot="footer" class="cellfooter"><text bindtap="handleMinus" data-item="{{item}}">-</text><text>{{item.number}}</text><text bindtap="handleAdd" data-item="{{item}}">+</text></view><view class="content"><!-- 内容区域的勾选栏 --><checkbox checked="{{item.checked}}" bindtap="handleChecked" data-item="{{item}}"></checkbox><!-- 商品图片 --><image src="http://localhost:5000{{item.good.poster}}" mode="aspectFit"></image><!-- 商品名称价格 --><view style="font-size: 26rpx;"><view>{{item.good.title}}</view><view style="color: red;">价格:{{item.good.price}}</view></view></view></mp-cell></mp-slideview></mp-cells><view wx:else style="text-align: center;">购物车空空如也~~~</view><!-- 计算总价 wxs --><wxs src="./shopcar.wxs" module="shopCarObj"></wxs><!-- 底部区域 --><view class="footer"><checkbox-group bindchange="handleSelectAll"><!-- 全选框 checked="" 实现绑定效果--><checkbox value="aaa" checked="{{shopCarObj.check(cartList)}}"></checkbox></checkbox-group><view style="margin-right: 20rpx;">全选</view><view>合计:¥{{shopCarObj.sum(cartList)}}</view><button type="primary" size="mini">去结算</button></view>
购物车商品总价及全选
1. 商品总价计算:
微信小程序
1. 不支持 Vue 的类似计算属性功能
2. 无法传参形式调用js 文件中的函数( 只能自定义属性data-xxx )
所以需要调用外部的 wxs 实现 !!!
// shopcar.wsx 计算总价的 wxsfunction sum(list){var total = 0for(var i =0;i<list.length;i++) {if(list[i].checked) {total+=list[i].good.price*list[i].number}}return total}function check(list) {if(list.length===0) return// every:所有item都为true的时候结果才是为true再将这个 true 给 return 出去return list.every(function(item){// 将判断的结果 true 返回给 every 去判断return item.checked==true})}module.exports = {sum:sum,check:check}
引入 wxs :
<!-- 计算总价 wxs --><wxs src="./shopcar.wxs" module="shopCarObj"></wxs><!-- 底部区域 --><view class="footer"><view>合计:¥{{shopCarObj.sum(cartList)}}</view></view>
计算总价,将购物车列表数据传入 wxs
function sum(list){var total = 0for(var i =0;i<list.length;i++) {if(list[i].checked) {total+=list[i].good.price*list[i].number}}return total}
判断选中 checked 的数据,将其进行遍历累加,return 总价出去
2. 商品全选框与单选框:
1. 单选框的选择改变全选框的 checked:
和计算商品总价相同,也需要引入外部的 wxs 实现逻辑判断
<!-- 计算总价 wxs --><wxs src="./shopcar.wxs" module="shopCarObj"></wxs><!-- 底部区域 --><view class="footer"><checkbox-group bindchange="handleSelectAll"><!-- 全选框 checked="" 实现绑定效果--><checkbox value="aaa" checked="{{shopCarObj.check(cartList)}}"></checkbox></checkbox-group><view style="margin-right: 20rpx;">全选</view></view>
将商品列表数据传入
全选框选中状态:checked="{{shopCarObj.check(cartList)}}"
function check(list) {if(list.length===0) return// every:所有item都为true的时候结果才是为true再将这个 true 给 return 出去return list.every(function(item){// 将判断的结果 true 返回给 every 去判断return item.checked==true})}
若数据为空:则无商品信息,return
数据不为空:
第一个return, 外面调用这个函数后需要一个结果,true / false 给外面的全选框 checked=""
第二个return,every()遍历 list 数据,每一项 item 判断结果都为 true,every()才为 true,将每一个 item 的判断返回给 every()
现在单选框的选择也会改变全选框的checked
2. 点击单选框取反:
点击单选框后,会对每个单选框的 checked 取反
// 点击商品选择框handleChecked(e){console.log(this.data.cartList);var item = e.currentTarget.dataset.itemitem.checked = !item.checkedthis.checkedUpdate(item)},
并且将最新状态 map 重写覆盖当前页面渲染的数据,且发送数据至服务器进行修改
// 重新计算最新更改的数据,且发送至存储数据库checkedUpdate(item){this.setData({cartList:this.data.cartList.map(data=>{if(data.id===item.id) {return item}return data})})request({url:`/carts/${item.id}`,method:'put',data:{"username": item.username,"tel": item.tel,"goodId": item.goodId,"number": item.number,"checked": item.checked,}})},
3. 点击全选框选中所有商品的单选框
通过绑定在checkedbox一个 value 值,来判断切换 true 和 false
// 点击底部全选选择框handleSelectAll(e){// 未全选if(e.detail.value.length===0) {this.setData({cartList:this.data.cartList.map(item=>({...item,checked:false}))})} // 全选else {this.setData({cartList:this.data.cartList.map(item=>({...item,checked:true}))})}},
商品数量的增加减少和删除
增加:
商品数量增加后,重新发送 put 请求更改数据库的数据
// 点击增加商品handleAdd(e){var item = e.currentTarget.dataset.itemitem.number++this.checkedUpdate(item)},
减少:
商品数量减少后,重新发送 put 请求更改数据库的数据
// 点击减少商品handleMinus(e){var item = e.currentTarget.dataset.itemif(item.number>1) {item.number--}this.checkedUpdate(item)},
删除:
用 filter()过滤掉选中的商品,重新发送 delete 请求删除数据库这条数据
// 点击左滑的删除按钮slideButtonTap(e){var id = e.currentTarget.dataset.idthis.setData({// false的过滤掉,true的继续装入cartListcartList:this.data.cartList.filter(item=>item.id!==id)})request({url:`/carts/${id}`,method:"delete"})},
商品加入购物车
1. 先用 CheckAuth()校验权限,若能在本地中获取到 token 和 电话号,则允许触发回调
2. 若未添加过购物车中,新建一条数据 post 请求发送至服务器修改数据
3. 若添加过购物车,将该商品数量 number +1 后,发送 put 请求至服务器修改数据
// 点击添加购物车handleAdd(){// 验证通过后可以触发回调函数CheckAuth(()=>{let {nickName} = wx.getStorageSync('token')let tel = wx.getStorageSync('tel')var goodId = this.data.info.idrequest({// 判断是否添加过购物车url:`/carts`,data:{username:nickName,tel,goodId}}).then(res=>{// 购物车没有添加过该商品,进行添加if(res.length===0) {return request({url:`/carts`,method:'post',data:{"username": nickName,"tel": tel,"goodId": goodId,"number": 1,"checked": false,}}).then(res=>{wx.showToast({title: '加入购物车成功',})setTimeout(()=>{wx.switchTab({url: '/pages/shopcar/shopcar',})},200)})} // 购物车添加过该商品,商品数量可以 + 1else {return request({url:`/carts/${res[0].id}`,method:'put',data:{...res[0],number:res[0].number+1}}).then(res=>{wx.showToast({title: '数量增加成功',})setTimeout(()=>{wx.switchTab({url: '/pages/shopcar/shopcar',})},200)})}})})},