购物车页面
2020-05-10 本文已影响0人
是新来的啊强呀
创建购物车页面,src/views/Cart.vue
<template>
<div>
...
<div class="container">
<div class="cart">
<div class="page-title-normal">
<h2 class="page-title-h2"><span>My Cart</span></h2>
</div>
<div class="item-list-wrap">
<div class="cart-item">
<div class="cart-item-head">
<ul>
<li>Items</li>
<li>Price</li>
<li>Quantity</li>
<li>Subtotal</li>
<li>Edit</li>
</ul>
</div>
<ul class="cart-item-list">
<li v-for="item in cartList">
<div class="cart-tab-1">
<div class="cart-item-check">
<a class="checkbox-btn item-check-btn" v-bind:class="{'check':item.checked=='1'}" @click="editCart('checked',item)">
<svg class="icon icon-ok">
<use xlink:href="#icon-ok"></use>
</svg>
</a>
</div>
<div class="cart-item-pic">
<img v-bind:src="'/static/'+item.productImage" v-bind:alt="item.productName">
</div>
<div class="cart-item-title">
<div class="item-name">{{item.productName}}</div>
</div>
</div>
<div class="cart-tab-2">
<div class="item-price">{{item.salePrice | currency('$')}}</div>
</div>
<div class="cart-tab-3">
<div class="item-quantity">
<div class="select-self select-self-open">
<div class="select-self-area">
<a class="input-sub" @click="editCart('minus',item)">-</a>
<span class="select-ipt">{{item.productNum}}</span>
<a class="input-add" @click="editCart('add',item)">+</a>
</div>
</div>
</div>
</div>
<div class="cart-tab-4">
<div class="item-price-total">{{item.productNum*item.salePrice | currency('$')}}</div>
</div>
<div class="cart-tab-5">
<div class="cart-item-opration">
<a href="javascript:;" class="item-edit-btn" @click="delCartConfirm(item.productId)">
<svg class="icon icon-del">
<use xlink:href="#icon-del"></use>
</svg>
</a>
</div>
</div>
</li>
</ul>
</div>
</div>
<div class="cart-foot-wrap">
<div class="cart-foot-inner">
<div class="cart-foot-l">
<div class="item-all-check">
<a href="javascipt:;" @click="toggleCheckAll">
<span class="checkbox-btn item-check-btn" v-bind:class="{'check':checkAllFlag}">
<svg class="icon icon-ok"><use xlink:href="#icon-ok"/></svg>
</span>
<span>Select all</span>
</a>
</div>
</div>
<div class="cart-foot-r">
<div class="item-total">
Item total: <span class="total-price">{{totalPrice | currency('$')}}</span>
</div>
<div class="btn-wrap">
<a class="btn btn--red">Checkout</a>
</div>
</div>
</div>
</div>
</div>
</div>
<modal v-bind:mdShow="modalConfirm" @close="closeModal">
<p slot="message">你确定要删除该条商品吗</p>
<div slot="btnGroup">
<a class="btn btn--m" href="javascript:;" @click="delCart">确认</a>
<a class="btn btn--m" href="javascript:;" @click="closeModal">关闭</a>
</div>
</modal>
...
</template>
<style>
...
</style>
<script>
import '../assets/css/checkout.css'
import NavFooter from '@/components/NavFooter.vue'
import NavHeader from '@/components/NavHeader.vue'
import NavBread from '@/components/NavBread'
import Modal from '@/components/Modal.vue'
import axios from '../../node_modules/axios/dist/axios.js'
export default{
data(){
return{
cartList:[],
modalConfirm:false,
productId:''
}
},
components:{
NavHeader,
NavFooter,
NavBread,
Modal
},
filters:{ // 过滤器,可以对数字进行格式化,使用方法 {{number | currency('$')}}
currency:currency
},
computed:{ // 实时计算,作用是,当有数据变化时,可以马上进行渲染
checkAllFlag(){ // 如果选中的商品数量等于购物车中商品总数量,返回true
return this.checkedCount == this.cartList.length;
},
checkedCount(){ // 计算选中的商品数量
var i = 0;
this.cartList.forEach((item)=>{
if(item.checked == '1')i++;
})
return i;
},
totalPrice(){ // 选中商品的总金额
var money = 0;
this.cartList.forEach((item)=>{
if(item.checked=='1'){ // 代表选中了的商品
money+=parseFloat(item.salePrice)*parseInt(item.productNum)
}
})
return money;
}
},
mounted() {
this.init();
},
methods:{
// 初始化,获取购物车数据
init(){
axios.get("/users/cartList").then((response)=>{
let res = response.data;
this.cartList = res.result;
})
},
// 删除商品的
delCart(){
axios.post("/users/cartDel",{productId:this.productId}).then((response)=>{
let res = response.data;
if(res.status == '0'){
this.modalConfirm = false;
this.init();
}
}
);
},
// 删除提示弹框方法
delCartConfirm(productId){
this.productId = productId
this.modalConfirm = true;
},
// 关闭弹框
closeModal(){
this.modalConfirm = false;
},
// 加减商品数量,商品选中
editCart(flag,item){
if(flag == 'add'){
item.productNum++;
}else if(flag == 'minus'){
if(item.productNum<=1){
return;
}
item.productNum--;
}else{
item.checked = item.checked=='1'?'0':'1';
}
axios.post("/users/cartEdit",{
productId:item.productId,
productNum:item.productNum,
checked:item.checked
}).then((response)=>{
let res = response.data;
})
},
// 购物车全选
toggleCheckAll(){
var flag = !this.checkAllFlag; // 注意checkAllFlag是实时计算,不能被赋值
this.cartList.forEach((item)=>{
item.checked = flag?'1':'0';
})
axios.post("/users/editCheckAll",{
checkAll:flag
}).then((response)=>{
let res = response.data;
if(res.status == '0'){
console.log("update suc")
}
})
}
}
}
</script>
增加购物车页面路由,src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import GoodsList from '@/views/GoodsList.vue'
import Cart from "@/views/Cart";
Vue.use(Router)
export default new Router({
routes: [
{
path: '/goods',
name: 'GoodsList',
component: GoodsList
},
{
path: '/cart',
name: 'Cart',
component: Cart
}
]
})
后端,创建查询购物车数据接口和删除商品接口,server/routes/users.js
// 查询当前用户的购物车数据
router.get('/cartList',function (req,res,next) {
var userId = req.cookies.userId;
User.findOne({userId:userId},function (err,doc) {
if(err){
res.json({
status:'1',
msg:err.message,
result:''
})
}else{
if(doc){
res.json({
status:'0',
msg:'',
result:doc.cartList
})
}
}
})
})
// 删除商品接口
router.post('/cartDel',function(req,res,next){
var userId = req.cookies.userId;
var productId = req.body.productId;
User.update({
userId:userId
},{
$pull:{
'cartList':{
'productId':productId
}
}
},function (err,doc) {
if(err){
res.json({
status:'1',
msg:err.message,
result:''
})
}else{
res.json({
status:'0',
msg:'',
result:'suc'
})
}
});
})
// 编辑购物车,商品数量增加,减少,商品选取
router.post('/cartEdit',function (req,res,next) {
var userId = req.cookies.userId;
var productNum = req.body.productNum;
var productId = req.body.productId;
var checked = req.body.checked;
User.update({userId:userId,"cartList.productId":productId},{
"cartList.$.productNum":productNum, // $占位符
"cartList.$.checked":checked
},function (err,doc) {
if(err){
res.json({
status:'1',
msg:err.message,
result:''
})
}else{
res.json({
status:'0',
msg:'',
result:'suc'
})
}
})
})
// 购物车全选
router.post("/editCheckAll", function (req,res,next) {
var userId = req.cookies.userId;
var checkAll = req.body.checkAll?'1':0;
// 获取到该用户的购物车商品数据
User.findOne({userId:userId}, function (err,user) {
if(err){
res.json({
status:'1',
msg:err.message,
result:''
});
}else{
if(user){
user.cartList.forEach((item)=>{ // 遍历每一个商品,把全选按钮的状况赋给每个商品的选择状态
item.checked = checkAll;
})
user.save(function (err1,doc) { // 保存信息
if(err1){
res.json({
status:'1',
msg:err1.message,
result:''
})
}else{
res.json({
status:'0',
msg:'',
result:'suc'
})
}
})
}
}
})
})