一、功能需求
- 1、購物車固定顯示在點餐頁面底部
- 2、實時統計購物車總數量和總金額
- 3、已選菜品展示在購物車
- 4、添加菜品到購物車(菜品列表增加和購物車內增加同步)
- 5、減少菜品到購物車(菜品列表減少和購物車內減少同步)
- 6、購物車蒙層的顯示和隱藏
- 7、購物車列表加載緩存菜品信息、已點菜品總數量、總金額
- 8、清空購物車
二、代碼實現
1、food.wxml
1 <!-- 搜索 --> 2 <view class="searchRoot"> 3 <input type="text" value="{{searchKey}}" class="searchInput" placeholder="搜索菜品" bindinput="getSearchContent" confirm-type="search" bindconfirm="searchFood"></input> 4 <image src="/images/search.png" class="searchIcon" bindtap="searchFood"></image> 5 </view> 6 7 <!-- 菜品列表 --> 8 <view class="hotFoodRoot"> 9 <view class="hotFoodItem" wx:for="{{foodList}}"> 10 <image src="{{item.icon}}"></image> 11 <view class="hotFoodText"> 12 <view class="itemName">{{item.name}}</view> 13 <view class="itemSell">銷量:{{item.sell}}</view> 14 <view class="addAndMinusRoot"> 15 <view class="itemPrice">{{item.price}}</view> 16 <!-- 菜品數量的加減 --> 17 <view class="addAndMinus"> 18 <image class="img" src="/images/minus.png" bindtap="minus" data-id="{{item._id}}"></image> 19 <text class="number">{{item.number}}</text> 20 <image class="img" src="/images/add.png" bindtap="add" data-id="{{item._id}}"></image> 21 </view> 22 </view> 23 </view> 24 </view> 25 </view> 26 <!-- 底部區域 --> 27 <view class="cartRoot"> 28 <view class="cartBackground"> 29 <image class="cartPackage" src="/images/package.png" bindtap="showCart"> 30 <view class="cartNumber"> 31 <text class="totalNumber">{{totalNumber}}</text> 32 </view> 33 </image> 34 <text class="totalMoney">{{totalMoney}}</text> 35 </view> 36 <view class="payMoney">選好了</view> 37 </view> 38 <!-- 購物車蒙層 --> 39 <view class="maskBackground" hidden="{{isHideMask}}"> 40 </view> 41 <!-- 購物車列表 --> 42 <view class="cartDetail" hidden="{{isHideMask}}"> 43 <!-- 標題 --> 44 <view class="cartTitle"> 45 <text class="foodTitle" bindtap="hideCart">返回</text> 46 <view class="delete" bindtap="clearCart"> 47 <image src="/images/delete.png"></image> 48 <text>清空</text> 49 </view> 50 </view> 51 <!-- 數據 --> 52 <scroll-view class="cartData"> 53 <view wx:for="{{cartList}}" class="cartItem"> 54 <image src="{{item.icon}}" class="cartImg"></image> 55 <view class="cartText"> 56 <view class="cartName">{{item.name}}</view> 57 <view class="cartMsg"> 58 <view class="cartPrice">{{item.price}}</view> 59 <!-- 菜品數量的加減 --> 60 <view class="addMinus"> 61 <image class="img" src="/images/minus.png" bindtap="minus" data-id="{{item._id}}"></image> 62 <text class="number">{{item.number}}</text> 63 <image class="img" src="/images/add.png" bindtap="add" data-id="{{item._id}}"></image> 64 </view> 65 </view> 66 </view> 67 </view> 68 </scroll-view> 69 </view>
2、food.wxss
1 /*搜索*/ 2 .searchRoot{ 3 display: flex; 4 flex-direction: row; 5 /*彈性盒內各項元素沿着主軸居中顯示*/ 6 align-items: center; 7 padding: 20rpx; 8 } 9 .searchInput{ 10 border: 1rpx solid #FF9966; 11 border-radius: 20rpx; 12 padding: 0 30rpx; 13 flex: 1; 14 height: 76rpx; 15 } 16 .searchIcon{ 17 width: 60rpx; 18 height: 60rpx; 19 margin-left: 20rpx; 20 } 21 /*菜品數據*/ 22 .hotFoodRoot{ 23 /*設置下內邊距,防止固定的購物車擋住最后一個菜品*/ 24 padding-bottom: 140rpx; 25 } 26 .hotFoodItem{ 27 display: flex; 28 margin: 20rpx 20rpx 0 20rpx; 29 border-bottom: 1rpx solid rgb(245, 245, 245); 30 } 31 .hotFoodItem image{ 32 width: 120rpx; 33 height: 120rpx; 34 margin-right: 20rpx; 35 border-radius: 10rpx; 36 /*防止標題過長把圖片擠走*/ 37 min-width: 120rpx; 38 } 39 40 .hotFoodItem .itemName{ 41 font-size: 32rpx; 42 /*設置菜品名稱超過一行時顯示省略號*/ 43 width: 500rpx; 44 white-space: nowrap; 45 text-overflow: ellipsis; 46 overflow: hidden; 47 } 48 .hotFoodItem .itemSell{ 49 font-size: 28rpx; 50 color: gray; 51 } 52 53 /*數量加減*/ 54 .addAndMinusRoot{ 55 display: flex; 56 justify-content: space-between; 57 align-items: center; 58 } 59 .addAndMinusRoot .itemPrice{ 60 font-size: 30rpx; 61 color: #FF9966; 62 } 63 .addAndMinusRoot .itemPrice::before{ 64 /*人民幣符號*/ 65 content: "¥"; 66 color:#FF9966; 67 } 68 .addAndMinusRoot .addAndMinus{ 69 display: flex; 70 justify-content: flex-end; 71 align-items: center; 72 } 73 .addAndMinus .img{ 74 margin: 0; 75 width: 50rpx; 76 /*必須加上min-width*/ 77 min-width: 50rpx; 78 height: 50rpx; 79 } 80 .addAndMinus .number{ 81 margin: 0 20rpx; 82 } 83 /*底部區域*/ 84 .cartRoot{ 85 width: 100%; 86 display: flex; 87 justify-content: center; 88 /*固定在底部*/ 89 position: fixed; 90 bottom: 20rpx; 91 z-index: 201; 92 } 93 .cartBackground{ 94 width: 450rpx; 95 height: 100rpx; 96 background-color:#fff; 97 border-top-left-radius: 50rpx; 98 border-bottom-left-radius: 50rpx; 99 box-shadow: 0 0 5px gainsboro; 100 display:flex; 101 justify-content: flex-start; 102 align-items: center; 103 } 104 .cartPackage{ 105 width: 80rpx; 106 height: 80rpx; 107 margin: 0 30rpx; 108 position: relative; 109 } 110 .cartNumber{ 111 width: 40rpx; 112 height: 40rpx; 113 border-radius: 50%; 114 background-color:red; 115 position: absolute; 116 top: 0; 117 right: 0; 118 display: flex; 119 align-items: center; 120 justify-content: center; 121 } 122 .totalNumber{ 123 font-size: 24rpx; 124 color: #fff; 125 line-height: 30rpx; 126 } 127 .totalMoney{ 128 font-size: 30rpx; 129 color: #ff9966; 130 } 131 .totalMoney::before{ 132 content: '¥'; 133 font-size: 20rpx; 134 color: #ff9966; 135 } 136 /*去結算*/ 137 .payMoney{ 138 width: 200rpx; 139 height: 100rpx; 140 background-color:#FF9966; 141 border-top-right-radius: 50rpx; 142 border-bottom-right-radius: 50rpx; 143 box-shadow: 0 0 5px gainsboro; 144 text-align: center; 145 line-height: 100rpx; 146 color: #fff; 147 } 148 /*購物車蒙層*/ 149 .maskBackground{ 150 position: fixed; 151 top: 0; 152 right: 0; 153 bottom: 0; 154 left: 0; 155 background-color: gray; 156 /*設置背景顏色透明度*/ 157 opacity: .4; 158 /*設置層級*/ 159 z-index: 100; 160 } 161 162 /*購物車詳情*/ 163 .cartDetail{ 164 position: fixed; 165 bottom: 0; 166 left: 0; 167 right: 0; 168 height: 600rpx; 169 background-color: #fff; 170 border-top-left-radius: 20rpx; 171 border-top-right-radius: 20rpx; 172 z-index: 200; 173 /*解決滑動沖突的問題*/ 174 overflow: auto; 175 /*底部內邊距,為購物車預留空間*/ 176 padding-bottom: 140rpx; 177 } 178 /*購物車標題*/ 179 .cartTitle{ 180 width: 100%; 181 display: flex; 182 justify-content: space-between; 183 align-items: center; 184 border-bottom: 1rpx solid #f2f2f2; 185 border-top-left-radius: 20rpx; 186 border-top-right-radius: 20rpx; 187 background-color: #fff; 188 height: 80rpx; 189 z-index: 201; 190 /*固定購物車標題*/ 191 position: fixed; 192 left: 0; 193 right: 0; 194 } 195 .cartTitle .foodTitle{ 196 font-size: 28rpx; 197 margin-left: 20rpx; 198 color: #FF9966; 199 } 200 .cartTitle .delete{ 201 display: flex; 202 align-items: center; 203 margin: 20rpx; 204 } 205 .delete image{ 206 width: 40rpx; 207 height: 40rpx; 208 margin-right: 5rpx; 209 } 210 .delete text{ 211 font-size: 28rpx; 212 color: #c3c3c3; 213 } 214 /*購物車數據*/ 215 .cartData{ 216 margin-top: 80rpx; 217 } 218 .cartItem{ 219 display: flex; 220 margin: 20rpx 20rpx 0 20rpx; 221 border-bottom: 1rpx solid rgb(245, 245, 245); 222 } 223 .cartItem .cartImg{ 224 width: 100rpx; 225 height: 100rpx; 226 border-radius: 10rpx; 227 margin-right: 20rpx; 228 /*防止標題過長把圖片擠走*/ 229 min-width: 100rpx; 230 } 231 .cartText{ 232 display: flex; 233 flex-direction: column; 234 justify-content:space-around; 235 } 236 .cartItem .cartName{ 237 font-size: 32rpx; 238 /*設置菜品名稱超過一行時顯示省略號*/ 239 width: 500rpx; 240 white-space: nowrap; 241 text-overflow: ellipsis; 242 overflow: hidden; 243 } 244 245 /*數量加減*/ 246 .cartMsg{ 247 display: flex; 248 justify-content: space-between; 249 align-items: center; 250 } 251 .cartPrice{ 252 font-size: 30rpx; 253 color: #FF9966; 254 } 255 .cartPrice::before{ 256 /*人民幣符號*/ 257 content: "¥"; 258 color:#FF9966; 259 } 260 .cartMsg .addMinus{ 261 display: flex; 262 justify-content: flex-end; 263 align-items: center; 264 } 265 .addMinus .img{ 266 margin: 0; 267 width: 50rpx; 268 /*必須加上min-width*/ 269 min-width: 50rpx; 270 height: 50rpx; 271 } 272 .addMinus .number{ 273 margin: 0 20rpx; 274 }
3、food.js
1 //定義db 2 const db = wx.cloud.database() 3 //搜索的菜品信息 4 let foodList = '' 5 //首頁傳遞過來的用戶輸入的搜索關鍵詞 6 let searchKey = '' 7 8 Page({ 9 //頁面的初始數據 10 data: { 11 //搜索內容 12 searchKey:'', 13 //搜索到的菜品數據 14 foodList:[], 15 //購物車的總數量、總金額、菜品信息 16 totalNumber:0, 17 totalMoney:0, 18 cartList:[], 19 //購物車蒙版是否隱藏 20 isHideMask:true 21 }, 22 23 //生命周期函數--監聽頁面加載 24 onLoad: function (options) { 25 //從首頁攜帶搜索詞 26 console.log("從首頁攜帶過來的搜索內容",options.searchKey); 27 searchKey = options.searchKey 28 //如果用戶輸入關鍵詞搜索 29 if(searchKey&&searchKey.length>0){ 30 this.setData({ 31 searchKey:searchKey 32 }) 33 }else{ //如果用戶不輸入關鍵詞搜索,則搜索所有菜品 34 searchKey = '' 35 } 36 //獲取購物車緩存數據(如果有緩存,則取緩存數據;如果無緩存,則為空數組) 37 let cart = wx.getStorageSync('cart') || [] 38 //將購物車緩存信息渲染到頁面上 39 this.setData({ 40 cartList:cart 41 }) 42 //調用自定義方法,執行搜索功能 43 this.searchFood(); 44 }, 45 46 //獲取用戶輸入的搜索內容 47 getSearchContent(e){ 48 console.log("用戶輸入的搜索內容",e.detail.value); 49 searchKey = e.detail.value 50 }, 51 52 //點擊搜索按鈕實現功能 53 searchFood(){ 54 console.log("用戶點擊了搜索按鈕,輸入的關鍵詞為",searchKey); 55 //購物車菜品信息 56 let cartList = this.data.cartList 57 //使用正則查詢 58 db.collection("food").where({ 59 name:db.RegExp({ 60 regexp:searchKey, //搜索池 61 options:'i' //不區分大小寫 62 }) 63 }).get() 64 .then(res=>{ 65 console.log("搜索成功",res); 66 foodList = res.data 67 if(foodList&&foodList.length>0){ 68 foodList.forEach(item=>{ 69 //遍歷數組foodList,為數組添加新字段number,賦值為0 70 item.number = 0 71 if(cartList&&cartList.length>0){ 72 //檢查當前購物車里是否存在當前所選的菜品 73 var res = cartList.find(cart=>{ 74 return cart._id == item._id 75 }) 76 if(res){ 77 item.number = res.number 78 }else{ 79 item.number = 0 80 } 81 } 82 }) 83 this.setData({ 84 foodList:foodList, 85 }) 86 //調用自定義方法,計算購物車總數量和總價格 87 this.getTotal() 88 } 89 }).catch(err=>{ 90 console.log("搜索失敗",err); 91 }) 92 }, 93 94 //點擊增加菜品數量 95 add(e){ 96 console.log("點擊了加",e.currentTarget.dataset.id); 97 let id = e.currentTarget.dataset.id 98 //購物車菜品信息 99 let cartList = this.data.cartList 100 //遍歷當前菜品數組 101 foodList.forEach(item=>{ 102 if(item._id==id){ 103 item.number+=1 104 //購物車所選菜品的信息 105 if(cartList&&cartList.length>0){ //如果購物車中有數據 106 //檢查當前購物車里是否存在當前所選的菜品 107 var res = cartList.find(cart=>{ 108 return cart._id == id 109 }) 110 console.log("當前所選的菜品是否存在於購物車里",res); 111 console.log("+++以后購物車的菜品列表",cartList); 112 //如果所選的菜品不在購物車里,直接添加到數組 113 if(!res){ 114 cartList.push(item) 115 }else{ 116 res.number = item.number 117 } 118 }else{ //如果購物車中無數據,直接push到數組 119 cartList.push(item) 120 } 121 } 122 }) 123 console.log("遍歷以后的當前菜品列表",foodList); 124 console.log("添加到購物車的菜品列表",cartList); 125 this.setData({ 126 //點擊添加之后的菜品列表信息 127 foodList:foodList, 128 //購物車所選商品列表 129 cartList:cartList 130 }) 131 //調用自定義方法,計算購物車總數量和總價格 132 this.getTotal() 133 //將數據存入緩存 134 wx.setStorageSync('cart', cartList) 135 }, 136 137 //點擊減少菜品數量 138 minus(e){ 139 console.log("點擊了減",e.currentTarget.dataset.id); 140 let id = e.currentTarget.dataset.id 141 //購物車菜品信息 142 let cartList = this.data.cartList 143 //遍歷當前菜品數組 144 foodList.forEach(item=>{ 145 if(item._id==id){ 146 if(item.number>0){ 147 item.number-=1 148 //購物車所選菜品的信息 149 if(cartList&&cartList.length>0){ //如果購物車中存在已選菜品 150 //查詢當前購物車里是否存在當前所選的菜品 151 var index = cartList.findIndex(cart=>{ 152 return cart._id == id 153 }) 154 if(index>-1){ 155 cartList[index].number = item.number 156 } 157 if(item.number == 0){ 158 cartList.splice(index,1) //刪除下標為index的1個元素 159 } 160 } 161 }else{ 162 wx.showToast({ 163 title: '數量不能小於0', 164 icon:'none' 165 }) 166 } 167 } 168 }) 169 console.log("遍歷以后的當前菜品列表",foodList); 170 console.log("---以后購物車的菜品列表",cartList); 171 this.setData({ 172 foodList:foodList, 173 //購物車所選商品列表 174 cartList:cartList 175 }) 176 //調用自定義方法,計算購物車總數量和總價格 177 this.getTotal() 178 //將數據存入緩存 179 wx.setStorageSync('cart', cartList) 180 }, 181 182 //自定義,計算購物車的總價格和總數量 183 getTotal(){ 184 //購物車的總數量、總金額、購物車菜品信息 185 let totalNumber = 0 186 let totalMoney = 0 187 let cartList = this.data.cartList 188 cartList.forEach(item=>{ 189 totalNumber+=item.number 190 totalMoney+=item.number*item.price 191 }) 192 this.setData({ 193 totalNumber:totalNumber, 194 totalMoney:totalMoney 195 }) 196 }, 197 198 //打開購物車蒙層 199 showCart(){ 200 this.setData({ 201 isHideMask:false 202 }) 203 }, 204 //關閉購物車蒙層 205 hideCart(){ 206 this.setData({ 207 isHideMask:true 208 }) 209 }, 210 211 //清空購物車 212 clearCart(){ 213 //把菜品列表所有菜品的數量置於0 214 let foodList = this.data.foodList //把菜品數據取出來 215 foodList.forEach(item=>{ //遍歷數組,把每個數量設為0 216 item.number =0 217 }) 218 //把購物車數組設為空數組 219 this.setData({ 220 foodList:foodList, 221 cartList:[], 222 totalNumber:0, 223 totalMoney:0 224 }) 225 //清空購物車緩存數據 226 wx.setStorageSync('cart', null) 227 }, 228 })
三、效果展示