vue+vuex购物车功能实现_东方凝落的博客-爱代码爱编程
效果图
在商品详情中设置一个加入购物车的按钮<button>
//goods是需要加入购物车的商品
<button @click="addToCart(goods)">加入购物车</button>
methods:{
//item是一个形参
addToCart(item){
//加入购物车
this.$store.dispatch('addCart',item);
}
}
购物车页面布局设计
src/components/Cart.vue创建一个vue文件Cart.vue
<!-- 购物车列表 -->
<div class="cart">
<!-- 购物车列表头部 -->
<ul class="m-inline-block">
<li class="inline-block item-goods">商品</li>
<li class="inline-block item-price">价格</li>
<li class="inline-block item-count">数量</li>
<li class="inline-block item-operate">操作</li>
</ul>
<!-- 标题 -->
<div class="cart-title">购物车</div>
<!-- 表身 -->
<div class="table-box-inner">
<table>
<!-- 遍历商品-->
<tr class="vFor" v-for="(item,index) in cartList" :key="index">
<td class="item-goods">
<!--选中商品-->
<input class="goods-input" type="checkbox" :checked=" item.item.checked" @click="selectItem(item)">
<!--商品图片-->
<a class="goods-a" href=""><img :src="item.item.img" alt=""></a> <!--商品详情-->
<div class="goods-info">
<h4>{{item.item.detail}}</h4>
</div>
</td>
<!--商品价格-->
<td class="item-price">
¥{{item.item.price}}
</td>
<td class="item-count">
<!--加商品-->
<button class="btn-add" @click="add(item.item)">+</button>
{{item.item.count}}
<!--减商品-->
<button class="btn-sub" @click="sub(item.item)">-</button>
</td>
<td class="item-operate">
<!--删除商品-->
<button class="btn-del" @click="del(index)">{{btnDel}}</button>
</td>
</tr>
</table>
</div>
</div>
<!-- 总计 -->
<div class="totals">
<div class="total">
<p>共 <em>{{totalNum}}</em> 件商品</p>
<p>总金额 <em>¥{{totalPrice}}</em>
</p>
</div>
<div class="pays" >
<div class="pay-p pay">请在倒计时结束前结算 |
总金额 <em>¥{{totalPrice}}</em>
</div>
<div class="pay-a pay">
<button @click="topay">立即结算</button>
</div>
</div>
</div>
Cart.vue中的<script>部分
//引入mapGetters
import { mapGetters } from 'vuex';
export default {
name:'Cart',
data(){
return {
},
computed:{
//保存的数据
//购物车选中结算的总价格和总数量
...mapGetters(['totalPrice']),
...mapGetters(['totalNum']),
cartList(){
//返回购物车中的商品数据
return this.$store.state.cartList;
},
},
methods:{
//点击商品的复选框
selectItem(item){
this.$store.dispatch("selectItem",item)
},
//加商品
add(item){
this.$store.dispatch("addItem", item);
},
//减商品
sub(item){
this.$store.dispatch("subItem", item);
},
//删除商品
del(index){
this.$store.dispatch("delete", index);
},
}
}
</script>
Cart.vue的CSS样式
/* 购物车列表 */
.m-inline-block{
width: 960px;
height: 38px;
border: 1px solid #e0e0e0;
line-height: 38px;
background-color: rgb(255,255,255);
margin: 0 auto;
position: relative;
}
.inline-block{
display: inline-block;
text-align: center;
}
.item-goods{
width: 400px;
}
.item-price{
width: 222px;
text-align: center;
}
.item-count{
width: 162px;
text-align: center;
}
.item-operate{
width: 174px;
text-align: center;
}
/* 标题 */
.cart-title{
width: 930px;
height: 24px;
font-size: 16px;
text-align: left;
color: #f10180;
margin: 20px auto;
position: relative;
}
.table-box-inner{
width: 960px;
margin: 0 auto;
position: relative;
border: 1px solid #ecebeb;
}
.vFor{
height: 100px;
padding-bottom: 10px;
}
/* 商品 */
.goods-input,.goods-a,.good-info{
float: left;
}
.goods-input{
position: relative;
margin: 30px 10px;
width: 20px;
height: 20px;
}
.goods-a{
left: 10px;
position: relative;
}
.goods-a img{
width: 100px;
height: 100px;
}
.goods-info{
position: relative;
left: 20px;
font-size: 12px;
width: 200px;
margin: 0 auto;
}
/* 价格 */
.vFor .item-price{
color:#f10180;
}
/* 操作 */
.btn-sub,.btn-del,.btn-add{
width: 50px;
height: 20px;
border:none;
background-color:antiquewhite;
}
/* 总计 */
.totals{
width: 960px;
height: 150px;
margin: 0 auto;
margin-top: 50px;
position: relative;
border: 1px solid #ecebeb;
/* border-bottom: none; */
}
.totals .total{
width: 200px;
height: 150px;
left: 760px;
position: relative;
text-align: center;
}
.totals .total p{
margin-top: 40px;
}
em{
color:#f10180;
}
/* 结算 */
.pays{
box-sizing: content-box;
position: fixed;
width: 960px;
height: 50px;
margin: 0 auto;
border: 1px solid #ecebeb;
bottom: 0;
}
.pay{
height: 50px;
line-height: 50px;
float: left;
}
.pay-p{
width: 760px;
text-align: right;
background-color: #f3f3f3;
color: #333;
padding-right: 30px;
}
.pay-a{
width: 200px;
text-align: center;
background-color:#f10180;
}
.pay-a button{
border: none;
color:#f9f9f9;
background-color:#f10180;
}
在store/index.js中
import Vue from "vue";
import Vuex from 'vuex';
Vue.use(Vuex)
//用于响应组件中的动作
const actions = {
//加入购物车
addCart(context,item){
context.commit('ADDCART',item)
alert("加入购物车成功");
},
//复选框
selectItem(context,item){
context.commit("SELECTITEM", item);
},
//加商品
addItem(context,item){
context.commit('ADDITEM',item);
},
//减商品
subItem(context,item){
context.commit('SUBITEM',item);
},
//删除商品
delete(context,index){
context.commit('DELETE',index);
}
};
//用于真正改变数据
const mutations = {
//加入购物车
ADDCART(state, item){
//判断本地是否有数据,默认没有
let flag = false;
//遍历在state中的cartList
state.cartList.map(ele => {
//判断state保存本地的id和传过来的id是否一样
if(ele.item.id == item.id){
flag = true;
ele.item.count++
}
})
console.log('item', item)
if(!flag){
state.cartList.push({item})
}
},
//复选框
SELECTITEM(state, item){
item.item.checked = !item.item.checked;
},
//加商品
ADDITEM(state,item){
item.count++;
},
//减商品
SUBITEM(state,item){
if(item.count > 1){
item.count--;
}
},
//删除商品
DELETE(state,index){
state.cartList.splice(index, 1);
},
};
//用于存放数据
const state = {
cartList:[],//存放购物车商品数据的数组
totalPrice:0,
totalNum: 0,
};
const getters = {
totalPrice: state => {
let totalNum = 0;
let totalPrice = 0;
state.cartList.filter(item => {
if(item.item.checked){
totalNum ++;
totalPrice += item.item.count * item.item.price;
}
})
return totalPrice;
},
totalNum: state => {
let totalNum = 0;
state.cartList.filter(item => {
if(item.item.checked){
totalNum += item.item.count;
}
})
return totalNum;
}
};
export default new Vuex.Store({
actions,
mutations,
state,
getters
})