用户进入购物车页面对其进行查看和管理。系统在商品详情页提供了加入购物车按钮,用户在浏览时遇到自己心仪的商品,但又暂时不想购买或犹豫不决,可以将其加入购物车以便二次查询。
在购物车里中点击商品可以进入对应商品详情页再次浏览,除此之外还提供了全选,单条/选中删除,结算等功能。购物车内标题栏有全选框,显示的每条商品信息前也有勾选框,点击批量删除或结算可以一次性对选中的商品进行对应功能处理。购物车界面如图
删除单条产品,当用户点击某条商品信息后对应的红色删除按钮时,即可删除对应商品。
删除所有选中的产品。批量删除,是通过全选按钮和商品勾选框结合实现。
结算后,结算的商品都要加入个人订单数据表。
点击查看详情。当用户点击某条商品信息时,跳转到对应详情页供用户查看详细信息。
对应代码:
<template> <div id="ShoppingCart"> <div class="ShoppingCart_box"> <h4 class="cart-title">购物清单</h4> <table> <!-- 标题栏 --> <tr class="product_title"> <td class="t_check" onselectstart="return false"> <span class="check_box" @click="selectProduct(isSelectAll)"> <i class="iconfont icon-duigou1" :class="{'check-true':isSelectAll}"></i> </span>全选 </td> <td colspan="2" class="t_name">名称</td> <td class="t_price">单价(元)</td> <td class="t_quantity">数量</td> <td class="t_total">总价(元)</td> <td class="t_delete">操作</td> </tr> <!-- 商品栏 --> <tr :key="index" v-for="(item,index) in productList"> <td> <span class="check_box" @click='item.select=!item.select'> <i class="iconfont icon-duigou1" :class="{'check-true':item.select}"></i> </span> </td> <td colspan="2" class="product_data" @click="viewdetails(item.proid,item.category,'购物车')"> <div class="p-img"> <img :src="item.img" class="p_img" alt=""> </div> <div class="p_info"> <p>{{item.name}}</p> <p>规格:{{item.size}}</p> </div> </td> <td class="p_price">¥{{item.price}}</td> <!-- 调整数量 --> <td class="p_quantity"> <input type="button" value="-" @click="subQuantity(item)"> <input class="quantity" type="text" v-model="item.quantity"> <input type="button" value="+" @click="addQuantity(item)"> </td> <td class="p_total">¥{{item.price*item.quantity}}</td> <td> <button class="p_delete" @click='deleteOneProduct(index,item.id)'>删除</button> </td> </tr> <!-- 购物车为空时显示 --> <tr> <td colspan="7" v-show="productList == undefined || productList.length <= 0" class="cartEmpty"> 购物车什么也没有,<span @click="$router.push({path:'/home/first'})">去逛逛></span> </td> </tr> </table> <!-- 统计结算行 --> <div class="statistic"> <button class="check_delete" @click='deleteCheckProduct'> <i class="iconfont icon-shanchu"></i>删除勾选商品 </button> <button class="buy" @click="displayPay = true">去结算</button> <div class="div_total"> <!-- 数量和总金额由计算属性得出 --> <span class="total_num">{{productTotal.quantity}}件商品总计:</span> <span class="total_price">¥{{productTotal.totalPrice}}元</span> </div> </div> <!-- 支付提示框 --> <div class="payAlert" :class="{payShow:displayPay}"> <h5>结算确认</h5> <img src="../../assets/imgs/pay.jpg" alt=""> <div class="payBtns"> <button class="payCancel" @click="displayPay = false">取消</button> <button class="payConfirm" @click="settle()">确认支付</button> </div> </div> </div> </div> </template> <script> import {getLoginData,getcoData,deletecoData,batchJoin} from '@/api/index' //订单号和创建时间函数封装 import {getTime,getNumber} from '@/assets/js/reuse' // 混入属性,页面跳转方法复用 import {productInfoMixin} from '@/assets/js/mixin' export default { name: 'ShoppingCart', // 混入对象 mixins:[productInfoMixin], data(){ return { productList:[], userdata:[], displayPay:false } }, mounted(){ // 获取商品数据 this.getcartList() // 获取用户数据 this.getUserdata() }, computed:{ // 检测是否全部勾选 isSelectAll() { // 如果数组为空,返回false if(this.productList == undefined || this.productList.length <= 0){ return false }else{ // 如果数组中中每一条数据的select都为true,才返回true,否则返回false return this.productList.every((value) => {return value.select}); } }, // 计算选择商品的总数和总价 productTotal() { // 获取list中select为true的数据,即被勾选了的商品 var List_true = this.productList.filter((item) => {return item.select}); var totalPrice = 0; for (var i = 0; i < List_true.length; i++) { // 总价 = 每种商品的数量*单价 totalPrice += List_true[i].quantity * List_true[i].price; } // 选择产品的件数:List_true.lenth,总价:totalPrice return{quantity:List_true.length,totalPrice:totalPrice} } }, methods:{ //给数组元素添加属性 addAttribute(){ //为productList添加select(用于判定是否勾选,初始值为false,即不选中) this.productList.map((item) =>{ //map:'键值对' this.$set(item,'select',false) //往item添加select属性,默认为false }) }, // 全选与取消全选 selectProduct(_isSelect){ //遍历productList,全部取反 for (var i = 0; i < this.productList.length; i++) { this.productList[i].select = !_isSelect } }, //数量- subQuantity(item){ if(item.quantity > 1){ item.quantity-- } }, //数量+ addQuantity(item){ //请求商品库存,传入商品类别,id getProInfo({ colname:'quantity', formname:'productlist', id:item.proid }) .then((res) =>{ // 计算库存是否足够 if(item.quantity < res[0].quantity){ item.quantity++ } }) }, //删除单条产品 deleteOneProduct(index,id){ //根据索引删除productList的记录 this.productList.splice(index,1); let idlist = [] idlist.push(id) this.deletecart(idlist) }, //删除所有选中的产品 deleteCheckProduct(){ let idlist = [] // 将所有选中的商品id存入数组 this.productList = this.productList.filter((item) => { if(item.select == true){ idlist.push(item.id) } return item.select == false }) this.deletecart(idlist) }, // 点击确认,选中商品一次性购买,将所有选中商品加入个人订单 settle(){ // 支付确认框隐藏 this.displayPay = false // 存放勾选商品信息 let selectList= [] // 存放勾选商品id let idlist = [] // 遍历整个购物车数据 this.productList = this.productList.filter((item) => { if(item.select == true){ // 将dataProcess处理好的这条信息加入数组 selectList.push(this.dataProcess(item)) idlist.push(item.id) } return item.select == false }) // 选中结算的商品,从购物车删除 this.deletecart(idlist) // 批量加入个人订单 batchJoin(selectList) .then((res) => { alert('勾选商品购买成功,已加入订单') }) .catch(error => { alert('批量添加失败') }) }, //将信息处理为一个符合订单数据表的数组格式 dataProcess(item){ let proarr = Object.values(item) // 将商品id置空,在订单表内会自增 proarr[0] = 0 // 将最后一个select属性去除 proarr.splice(-1) // 加入状态(status)值,结算后应为待收货即1 proarr.push(1) // 加入收货人信息 proarr.push(this.userdata.name,this.userdata.phone,this.userdata.place) //获取订单创建时间 let timedata = getTime() //订单时间 proarr.push(timedata.time) //订单号编写 let orderNumber = getNumber(timedata.orderNumTime,item.proid,item.category) //把这一条订单信息加入数组 proarr.push(orderNumber) return proarr }, // 获取购物车数据 getcartList(){ getcoData({ formname:'shoppingcart', username:sessionStorage.getItem("userName") }) .then((res) => { this.productList = res // 添加用于判断勾选的属性 this.addAttribute() }) .catch(error => { alert('获取失败') }) }, //删除购物车数据 deletecart(idlist){ deletecoData({ formname:'shoppingcart', idlist:idlist }) .then((res) => { // // 重新获取购物车数据 // this.getcartList() }) .catch(error => { alert('删除失败') }) }, // 获取用户数据作为默认收货人 getUserdata(){ let userName = sessionStorage.getItem("userName") getLoginData({username: userName}) .then(res => { this.userdata = res[0] }) } } } </script> <style scoped> /* 图片名称处样式订单和购物车相同,所以复用 */ @import '../../assets/css/cartorder.css'; /* 支付提示框 */ @import '../../assets/css/payAlert.css'; *{ margin: 0; padding: 0; list-style: none; } #ShoppingCart{ width: 100%; } .ShoppingCart_box{ border: 1px solid #aaa; border-top: 2px solid rgb(131, 131, 226); width: 1020px; margin: 50px auto; position: relative; } .cart-title{ font-size: 25px; color: #66b1ff; text-align: center; line-height: 60px; } table{ border-collapse: collapse; } /* 标题栏 */ .product_title{ background-color: #f7f7f7; border-top: 1px solid #e3e3e3; border-bottom: 1px solid #e3e3e3; } .product_title td{ text-align: center; height: 38px; line-height: 38px; } .t_check{ width: 100px; } .t_name{ width: 350px; } .t_price{ width: 100px; } .t_quantity{ width: 210px; } .t_total{ width: 120px; } .t_delete{ width: 140px; } table .check_box{ display: block; width: 20px; height: 20px; float: left; border: 1px solid #e3e3e3; background-color: white; margin: 8px 5px 8px 15px; position: relative; } .product_title td .icon-duigou1{ line-height: 20px; } .icon-duigou1{ color: red; margin-left: 2px; display: none; } .check-true{display: block;} /* 商品栏 */ .p_price{ text-align: center; color: #e92846; } /* 调整数量的按键 */ .p_quantity{ padding: 0 30px; } table input{ border: #e3e3e3 solid 1px; padding: 5px 10px; color: #848484; font-size: 16px; cursor: pointer; margin-left: 10px; } .quantity{ width: 30px; color: black; text-align: center; font-size: 14px; } .p_total{ text-align: center; color: #e92846; } .p_delete{ width: 80px; height: 30px; background-color: #fd3729; border: none; margin: 0 30px; border-radius: 8px; color: white; cursor: pointer; } /* 购物车为空时提示字 */ .cartEmpty{ width: 1005px; height: 100px; text-align: center; } .cartEmpty span{ color: blue; cursor: pointer; } /* 统计结算行 */ .statistic{ height: 40px; background-color: #eeecec; } .check_delete{ font-size: 14px; color: #333; padding: 0 10px; margin-top: 10px; cursor: pointer; border: none; } .buy,.div_total{ float: right; } .div_total{ margin-top: 10px; } .total_price{ color: #e92846; } .buy{ margin-left: 20px; width: 100px; height: 40px; border: none; color: #fff; font-size: 18px; text-align: center; background-color: #ff3300; border: 1px solid #eeecec; cursor: pointer; } /* 结算提示框 */ .payAlert{ height: 280px; top: -400px; left: 300px; } .payShow{ top: 130px; left: 300px; } </style>