vue购物车
2018-11-01 本文已影响0人
两年半练习程序员
shopCart.gif
源码下载https://gitee.com/httpchc320321/vueShopCart.git
功能介绍
1.商品数据加载
2.计算商品数量,选中的商品总价
3.单选
4.单个删除
5.数量加减,对应改变此商品总额
6.全选
7.批量删除
HTML和CSS不再做介绍直接贴代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>vue购物车</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<div id="shopCart" class="container shopCartBox">
<div class="cart-filter-bar">
<div class="switch-cart" id="cart_num">
<!-- 购物车数量 -->
<span class="color">
我的购物车
<em class="color">{{goodsNum}}</em>
</span>
</div>
</div>
<!-- 列标题 -->
<div class="col-sm-12">
<div class="col-sm-1 columnTiele">选择</div>
<div class="col-sm-6 columnTiele">商品信息</div>
<div class="col-sm-1 columnTiele">单价(元)</div>
<div class="col-sm-2 columnTiele">数量</div>
<div class="col-sm-1 columnTiele">金额(元)</div>
<div class="col-sm-1 columnTiele">操作</div>
<!-- 商品box -->
<div class="order-content col-sm-12">
<!-- 商品 item-->
<div class="item-list" v-for="(item,index) in goodsList">
<!-- 选择 -->
<div class="col-sm-1">
<input class="goodsChoice" name="selGoods" @click='checkInput(index)' :checked='item.state' type="checkbox">
</div>
<!-- 图片+标题 -->
<div class="col-sm-6 item_img">
<a href="">
<img :src="item.img" alt="">
</a>
<div class="item_title"><a href="">{{item.title}}</a></div>
</div>
<!-- 单价 -->
<div class="col-sm-1">
<p class="item_originalPrice">¥{{item.price}}</p>
<p class="item_price">¥{{item.price}}</p>
</div>
<!-- 数量 -->
<div class="col-sm-2">
<p class="item_num" @click='reduceNum(index)'>-</p>
<p class="item_num">{{item.num}}</p>
<p class="item_num" @click='addNum(index)'>+</p>
</div>
<!-- 金额 -->
<div class="col-sm-1 item_totalPrice">
<p>¥{{item.total}}</p>
</div>
<!-- 操作 -->
<div class="col-sm-1">
<a class="item_del" href="javascript:void(0);" @click='delGoods(index)'>删除</a>
</div>
</div>
</div>
<!-- 结算统计 begin-->
<div class="col-sm-12 cart-foot">
<!-- 全选 -->
<div class="col-sm-1">
<input class="allChoice" v-model="allChoice" name="allSel" type="checkbox">全选
</div>
<!-- 删除 -->
<div class="col-sm-1">
<a class="item_del" @click='delSelGoods' href="javascript:void(0);">删除</a>
</div>
<!-- 合计 -->
<div class="col-sm-9 ">
<strong class="total">¥{{goodsTotal}}</strong>
<span class="txt">合计(不含运费):</span>
</div>
<!-- 结算 -->
<div class="col-sm-1 settlement">结算</div>
</div>
<!-- 结算统计 end-->
</div>
</div>
</body>
</html>
css
<style>
*{margin: 0;padding: 0;}
.container{width: 1200px;margin: 0 auto;}
.col-sm-12,.col-sm-9,.col-sm-6,.col-sm-2,.col-sm-1{float: left;position: relative;min-height: 1px;padding-right: 15px;padding-left: 15px;box-sizing: border-box;}
.col-sm-12{width: 100%;}
.col-sm-9{width: 75%;}
.col-sm-6{width: 50%;}
.col-sm-2{width: 16.66666667%;}
.col-sm-1{width: 8.33333333%;}
/* 购物车商品 */
.cart-filter-bar{
margin-top: 15px;
height: 33px;
font-size: 12px;
position: relative;
border-bottom: 2px #e5e5e5 solid;
}
.cart-filter-bar .switch-cart{
height: 33px;
float: left;
border-bottom: 2px solid red;
}
.cart-filter-bar .switch-cart span{
float: left;
font-size: 18px;
height: 18px;
line-height: 1.1;
padding-bottom: 15px;
cursor: pointer;
margin-left: -1px;
display: inline-block;
color: red;
}
.cart-filter-bar .switch-cart span em{
margin: 0 5px;
}
.shopCartBox .columnTiele{
color: #3c3c3c;
font-size: 12px;
line-height: 50px;
}
.allChoice{
width: 15px;
height: 15px;
float: left;
margin-top: 17px !important;
cursor: pointer;
}
.goodsChoice{
width: 15px;
height: 15px;
cursor: pointer;
}
/* 商品列表 */
.order-content{
border: 1px solid #e5e5e5;
padding: 0;
background: #fcfcfc;
}
.order-content .item-list{
padding: 15px 0;
border-bottom: 1px solid #e5e5e5;
}
.order-content .item-list:after{
content: '';
display: block;
clear: both;
}
.order-content .item-list .item_img{
padding: 0;
margin: 0;
}
.order-content .item-list .item_img img{
border: 1px solid #eee;
vertical-align: middle;
float: left;
max-height: 80px;
max-width: 80px;
}
.order-content .item-list .item_title{
max-width: 300px;
font-size: 12px;
white-space: normal;
margin-left: 90px;
}
.order-content .item-list .item_title a{
color: #666;
text-decoration: none;
outline: none;
}
.order-content .item-list .item_originalPrice{
color: #999;
text-decoration: line-through;
font-size: 12px;
}
.order-content .item-list .item_price{
color: #666;
font-weight: 600;
font-size: 14px;
}
.order-content .item-list .item_totalPrice{
color: #E31939;
font-weight: 700;
font-size: 14px;
}
.order-content .item-list .item_num{
text-align: center;
line-height: 30px;
padding: 0 10px;
margin-right: 1px;
border:1px solid #e5e5e5;
box-sizing: border-box;
float: left;
-webkit-user-select: none;
}
.item_del{
color: #666;
display: block;
text-decoration: none;
}
.item_del:hover{
color: #E31939;
text-decoration: none;
}
.cart-foot{
position: relative;
height: 50px;
line-height: 50px;
background: #e5e5e5;
margin-top: 20px;
font-size: 12px;
padding: 0;
}
.cart-foot .txt{
line-height: 50px;
float: right;
}
.cart-foot .total{
font-weight: 400;
font-size: 20px;
font-weight: bold;
line-height: 48px;
margin: 0 5px;
vertical-align: middle;
float: right;
color: #E31939;
}
.cart-foot .settlement{
display: inline-block;
background: #f40;
color: #fff;
text-align: center;
font-size: 20px;
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
-ms-border-radius: 2px;
border-radius: 2px;
text-decoration: none;
cursor: pointer;
}
</style>
1.商品数据加载
记得引入vue
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
在vue挂载完毕后数据添加到data中,此时数据会在html中加载出来
<script>
var vue = new Vue({
el: '#shopCart',
data: {
goodsList:[],//商品列表
goodsNum:0,//商品数量
goodsTotal:0,//商品总价
allChoice:false//全选
},
methods: {
},
//挂载完毕
mounted() {
this.goodsList=[{
title:'大米',//名称
price:'48.00',//单价
img:'http://kinguv.oss-cn-beijing.aliyuncs.com/images/shop/1/gallery/2018/08/01/15330886127335.jpg?x-oss-process=image/resize,m_pad,limit_0,h_220,w_220',
num:1,//数量
total:48,//总价
state:false//选中煮状态
},
{
title:'小米',
price:'80.00',
img:'http://kinguv.oss-cn-beijing.aliyuncs.com/images/shop/1/gallery/2018/08/01/15330886127335.jpg?x-oss-process=image/resize,m_pad,limit_0,h_220,w_220',
num:1,
total:80,
state:false
}];
}
})
</script>
2.计算商品数量,选中的商品总价
计算购物车商品总数量和选中商品总价经常会在商品数量添加以及选中和删除商品时调用,所以我们在mothods
中定义一个allTotal()
方法方便调用
//计算总价格
allTotal:function(e){
//商品总价
this.goodsTotal=0;
for(var i=0;i<this.goodsList.length;i++){
//此商品是否选中
if(this.goodsList[i].state){
this.goodsTotal+=this.goodsList[i].price*this.goodsList[i].num
}
}
//商品总数量
this.goodsNum=this.goodsList.length;
}
3.选中/取消商品
在商品的checkbox上添加点击事件checkInput(index)
,index为当前商品在商品列表里的下标
<input class="goodsChoice" name="selGoods" @click='checkInput(index)' :checked='item.state' type="checkbox">
当选择/取消商品时,更改商品选中状态,并重新计算商品总额
// 选择商品
checkInput:function(e){
console.log(e)
this.goodsList[e].state=!this.goodsList[e].state;
// 计算总价
this.allTotal();
},
4.单个删除
在商品的checkbox上添加删除点击事件delGoods(index)
<!-- 操作 -->
<div class="col-sm-1">
<a class="item_del" href="javascript:void(0);" @click='delGoods(index)'>删除</a>
</div>
当删除商品时,将商品从商品列表goodsList
中移除,并重新计算商品总额
// 单个删除商品
delGoods:function(e){
this.goodsList.splice(e,1);
// 计算总价
this.allTotal();
},
5.数量加减,对应改变此商品总额
在商品数量+
,-
分别添加点击事件addNum(index)
,reduce(index)
<!-- 数量 -->
<div class="col-sm-2">
<p class="item_num" @click='reduceNum(index)'>-</p>
<p class="item_num">{{item.num}}</p>
<p class="item_num" @click='addNum(index)'>+</p>
</div>
在加减数量同时改变此商品的总额,即商品单价*商品数量
,若在减商品数量时数量已经为0,则不可继续减少,在加减数量结束时计算全部选中的商品总额
//商品数量减
reduceNum:function(e){
if(this.goodsList[e].num==0){
return false;
}
this.goodsList[e].num--;
this.goodsList[e].total=this.goodsList[e].price*this.goodsList[e].num
this.allTotal();
},
//商品数量加
addNum:function(e){
this.goodsList[e].num++;
this.goodsList[e].total=this.goodsList[e].price*this.goodsList[e].num
this.allTotal();
},
6.全选
全选用到了监听watch
,监听allChoice
值变化,allChoice
绑定到了全选check上
<!-- 全选 -->
<div class="col-sm-1">
<input class="allChoice" v-model="allChoice" name="allSel" type="checkbox">全选
</div>
当选中全选时,allChoice
会改变成'true',触发监听watch
,将商品选中状态更改为全选的选中状态,并计算总金额
watch: {
// 全选
allChoice:function(val){
console.log('watch:'+val)
for(var i=0;i<this.goodsList.length;i++){
this.goodsList[i].state=val;
}
this.allTotal();
}
},
7.批量删除
将已选中的商品从商品列表goodsList
中移除,并计算此时总金额
//删除选中商品(批量删除)
delSelGoods:function(e){
var newGoodsList=[];
for(var i=0;i<this.goodsList.length;i++){
if(!this.goodsList[i].state){
newGoodsList.push(this.goodsList[i])
}
}
this.goodsList=newGoodsList;
// 计算总价
this.allTotal();
},
完整js如下
<script>
var vue = new Vue({
el: '#shopCart',
data: {
goodsList:[],//商品列表
goodsNum:0,//商品数量
goodsTotal:0,//商品总价
allChoice:false//全选
},
filters: {},
computed: {
},
methods: {
// 单个删除商品
delGoods:function(e){
this.goodsList.splice(e,1);
// 计算总价
this.allTotal();
},
//删除选中商品(批量删除)
delSelGoods:function(e){
var newGoodsList=[];
for(var i=0;i<this.goodsList.length;i++){
if(!this.goodsList[i].state){
newGoodsList.push(this.goodsList[i])
}
}
this.goodsList=newGoodsList;
// 计算总价
this.allTotal();
},
// 选择商品
checkInput:function(e){
console.log(e)
this.goodsList[e].state=!this.goodsList[e].state;
// 计算总价
this.allTotal();
},
//商品数量减
reduceNum:function(e){
if(this.goodsList[e].num==0){
return false;
}
this.goodsList[e].num--;
this.goodsList[e].total=this.goodsList[e].price*this.goodsList[e].num
this.allTotal();
},
//商品数量加
addNum:function(e){
this.goodsList[e].num++;
this.goodsList[e].total=this.goodsList[e].price*this.goodsList[e].num
this.allTotal();
},
//计算总价格
allTotal:function(e){
this.goodsTotal=0;
for(var i=0;i<this.goodsList.length;i++){
if(this.goodsList[i].state){
this.goodsTotal+=this.goodsList[i].price*this.goodsList[i].num
}
}
this.goodsNum=this.goodsList.length;
}
},
watch: {
// 全选
allChoice:function(val){
console.log('watch:'+val)
for(var i=0;i<this.goodsList.length;i++){
this.goodsList[i].state=val;
}
this.allTotal();
}
},
//此阶段为实例初始化之后,此时的数据观察和事件配置都没好准备好。
//创建前
beforeCreate() {
console.log('beforeCreate!!!!!!!!!');
console.log('el:', this.$el);
console.log('data:', this.$data);
},
//能读取到数据data的值,但是DOM还没生成
//创建成功
created() {
console.log('created!!!!!!!!!');
console.log('el:', this.$el);
console.log('data:', this.$data);
},
//能读取到数据data的值,DOM已生成,但dom还无法渲染data
//挂载前
beforeMount() {
console.log('beforeMount!!!!!!!!!');
console.log('el:', this.$el);
console.log('data:', this.$data);
},
//挂载完毕
mounted() {
console.log('mounted!!!!!!!!!');
console.log('el:', this.$el);
console.log('data:', this.$data);
this.goodsList=[{
title:'大米',
price:'48.00',
img:'http://kinguv.oss-cn-beijing.aliyuncs.com/images/shop/1/gallery/2018/08/01/15330886127335.jpg?x-oss-process=image/resize,m_pad,limit_0,h_220,w_220',
num:1,
total:48,
state:false
},
{
title:'小米',
price:'80.00',
img:'http://kinguv.oss-cn-beijing.aliyuncs.com/images/shop/1/gallery/2018/08/01/15330886127335.jpg?x-oss-process=image/resize,m_pad,limit_0,h_220,w_220',
num:1,
total:80,
state:false
}];
this.allTotal();
},
//更新视图
beforeUpdate() {
console.log('beforeUpdate!!!!!!!!!');
},
//更新完成
updated() {
console.log('updated!!!!!!!!!');
},
beforeDestroy() {
console.log('beforeDestroy!!!!!!!!!');
},
destroyed() {
console.log('destroyed!!!!!!!!!');
}
})
</script>
点赞.jpg