Vue案例:商品购物车(三)
底部合计
合计就是把选中商品的金额全部加到一起,当然它也不止这点功能,它还可以看你选了几件商品,还有批量删除功能,最左边还有一个跟顶部一样的全选框。
批量删除功能:
allDel() {
this.Commodity =
this.Commodity.filter(item => {
// console.log(item)
return item.decide === false
});
},
选中的商品:
settle() {
let a = 0
this.Commodity.forEach(item => {
if (item.decide === true) {
a++
}
})
return a
}
这个底部合计虽然是在底部的,但是在商品列表很长的时候,它其实是会出现在屏幕的最下方的,等到,用户到达最下方的时候会重新回归原位。
scrollToTop() {
// 获取视窗高度
let domHight = document.body.offsetHeight;
// dom滚动位置
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
// 获取窗口高度
let height = document.documentElement.clientHeight + 100
// 元素的高度
// let summarize = this.$refs.summarize.scrollTop
if (domHight <= 600) {
return
}
if (domHight < scrollTop + height) {
this.fixed = false
} else {
this.fixed = true
}
}
},
mounted() {
window.addEventListener('scroll', this.scrollToTop);
},
destroyed() {
// 跳页的时候销毁
window.removeEventListener('scroll', '')
},
好了,差不多这个案例的功能,和实现原理就讲完了,下面有这个案例的全部代码,如果有什么不好的地方,大家可以批评。
这是全部代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>商品购物车</title>
<link rel="stylesheet" href="./css/index.css">
</head>
<body>
<div id="app">
<div class="big-box">
<div class="title-box" ref="title">
<div class="checktext">
<i :class='{allCheck:all,checkbox:true}' @click='allCheck'></i>
<span>全选</span>
</div>
<div class="text-box">
<span>单价</span>
<span>数量</span>
<span>小计(元)</span>
<span @click='last'>{{del?'完成':'编辑'}}</span>
</div>
</div>
<ul class="content-box">
<li v-for='(item,index) in Commodity'>
<div class="img-box">
<div class="img-check">
<i :class='{allCheck:item.decide,checkbox:true}' @click='decideCheck(index)'></i>
<img :src="item.src" alt="">
</div>
<div class="introduce">
<p>{{item.name}}</p>
<p>{{item.text}}</p>
</div>
</div>
<div class="money">
<div>¥<strong>{{item.money.toFixed(2)}}</strong></div>
<div class="quantity-box">
<div class="quantity">
<span @click='minus(index)'
:style="{'cursor':item.quantity<=1?'no-drop':'pointer'}">-</span>
<input type="number" @blur='lose' v-model='item.quantity'>
<span @click='add(index)'
:style="{'cursor':item.quantity>=50?'no-drop':'pointer'}">+</span>
</div>
<p>最多能只能买50件</p>
</div>
<div style="color: red;">¥<strong>{{item.subtotal.toFixed(2)}}</strong></div>
<div class="del-box">
<p :style="{'display':del? 'none':'block'}">--</p>
<i :style="{'display':del?'inline-block':'none'}" class="del" @click='deleteLi(index)'></i>
</div>
</div>
</li>
</ul>
<div class="summarize-box">
<div :class='{summarize:true,summarizeFixed:fixed}' ref="summarize">
<div class="summarizeLeft">
<div class="summarizeCheck">
<i :class='{allCheck:all,checkbox:true}' @click='allCheck'></i>
<span>全选</span>
</div>
<p @click='allDel'>删除选中的商品</p>
<p>一共有{{summarize}}件商品,已经选了<strong style="color: #47e3ee;">{{settle}}</strong>件</p>
</div>
<div class="summarizeRight">
<p>合计(不包运费):<strong>¥{{allMoney.toFixed(2)}}</strong></p>
<button>购买</button>
</div>
</div>
</div>
</div>
</div>
<script src="../../js/vue.js"></script>
<script src="./js/index.js"></script>
</body>
</html>
body {
margin: 0;
padding: 0;
}
span,
p,
input,
i,
ul,
li,
input,
button,
strong {
margin: 0;
padding: 0;
list-style: none;
}
.big-box {
width: 100%;
height: auto;
margin: 0 auto;
background-color: #edfcfd;
box-shadow: 0 1px 6px #999;
overflow: hidden;
}
.title-box {
width: 100%;
height: 48px;
background-color: #f5f5f5;
box-shadow: 0 1px 1px #d1d1d1;
display: flex;
justify-content: space-evenly;
align-items: center;
padding: 0 10px;
margin: 0 auto;
}
.title-box div {
height: 100%;
line-height: 48px;
color: #999;
}
/* 全选 */
.checktext {
width: 40%;
display: flex;
align-items: center;
}
.checktext span {
font-size: 18px;
color: #333;
}
/* 介绍 */
.text-box {
width: 60%;
text-align: center;
overflow: hidden;
}
.text-box span {
float: left;
width: 25%;
height: 100%;
font-weight: 300;
}
.text-box span:last-child {
color: #47e3ee;
cursor: pointer;
}
.checkbox {
display: block;
width: 18px;
height: 18px;
margin-right: 5px;
border: 1px solid #777;
cursor: pointer;
}
.allCheck {
background: url('../images/yes.png') no-repeat;
background-size: 18px;
background-color: #47e3ee;
}
/* 商品区 */
.content-box {
height: auto;
width: 100%;
background-color: #edfcfd;
}
.content-box li {
height: 180px;
width: 100%;
box-shadow: 0 1px 3px #d1d1d1;
margin: 4px 0;
background-color: white;
}
.img-box {
float: left;
width: 40%;
height: 100%;
}
.img-check {
float: left;
width: 50%;
height: 100%;
display: flex;
align-items: center;
justify-content: space-around;
overflow: hidden;
}
.img-check img {
max-width: 140px;
min-height: 120px;
}
.introduce {
float: left;
width: 50%;
height: 100%;
overflow: hidden;
}
.introduce p {
color: #333;
font-size: 18px;
width: 100%;
height: auto;
margin-top: 40px;
margin-left: 10px;
word-wrap: break-word;
word-break: normal;
}
.introduce p:nth-child(2) {
margin-top: 0;
font-size: 16px;
color: #999;
font-weight: 300;
}
.money {
float: left;
width: 60%;
height: 100%;
line-height: 180px;
}
.money div {
float: left;
width: 25%;
height: 100%;
text-align: center;
font-size: 20px;
color: #333;
}
.quantity-box {
display: flex;
flex-direction: column;
justify-content: center;
overflow: hidden;
}
.quantity-box .quantity {
display: flex;
justify-content: center;
align-items: flex-end;
width: 100%;
height: 46px;
}
.quantity-box .quantity span {
width: 24px;
height: 26px;
border: 1px solid #99999966;
line-height: 26px;
color: #777;
user-select: none;
}
.quantity-box .quantity span:hover {
color: #47e3ee;
}
.quantity input {
width: 50px;
height: 26px;
outline: none;
border: 0;
border-top: 1px solid #99999966;
border-bottom: 1px solid #99999966;
text-align: center;
}
.quantity-box p {
float: left;
width: 100%;
height: 20px;
color: #999;
font-size: 14px;
line-height: 2;
}
.quantity input::-webkit-outer-spin-button,
.quantity input::-webkit-inner-spin-button {
-webkit-appearance: none !important;
margin: 0;
}
.money div .del {
display: inline-block;
width: 20px;
height: 20px;
background: url('../images/del.png') no-repeat;
background-size: 20px;
cursor: pointer;
}
.summarize-box {
width: 100%;
height: 120px;
}
.summarize {
width: 100%;
height: 120px;
margin: 20px 0;
background-color: white;
box-shadow: 0 1px 3px rgb(153, 153, 153);
color: #999;
}
.summarizeFixed {
position: fixed;
bottom: 0;
left: 0;
margin: 0;
height: 120px;
}
.summarize .summarizeLeft {
float: left;
width: 50%;
height: 100%;
line-height: 80px;
display: flex;
align-items: center;
}
.summarize .summarizeLeft p {
margin-left: 20px;
user-select: none;
}
.summarize .summarizeLeft p:first-of-type:hover {
color: #47e3ee;
cursor: pointer;
}
.summarizeLeft .summarizeCheck {
width: auto;
height: 100%;
margin-left: 20px;
display: flex;
align-items: center;
}
.summarize .summarizeRight {
float: left;
width: 50%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.summarize .summarizeRight strong {
font-size: 20px;
color: red;
}
.summarize .summarizeRight button {
width: 120px;
height: 40px;
background-color: #ff5f5f;
color: white;
border: 0;
font-size: 16px;
box-shadow: 0 1px 1px #999;
margin-left: 20px;
border-radius: 5px;
cursor: pointer;
}
Vue.config.productionTip = false
new Vue({
el: '#app',
data: {
Commodity: [{
name: '相机',
text: '一亿像素,画面更清晰',
src: './images/camera.jpeg',
// 数量
quantity: 1,
// 单价
money: 99.10,
// 小计
subtotal: 0,
decide: false
}, {
name: '毛绒衬衫',
text: '最新推出,八折优惠',
src: './images/clothes1.jpeg',
quantity: 1,
money: 128.88,
subtotal: 0,
decide: false
}, {
name: '保暖大衣',
text: '冬季的必备物品',
src: './images/clothes2.jpeg',
quantity: 1,
money: 246.9,
subtotal: 0,
decide: false
}, {
name: 'vivo X70 Pro',
text: '最新推出的vivo手机',
src: './images/mobile.jpg',
quantity: 1,
money: 3999,
subtotal: 0,
decide: false
}, {
name: '电动牙刷',
text: '一次充电,超长续航',
src: './images/toothbrush.jpg',
quantity: 1,
money: 399,
subtotal: 0,
decide: false
}, {
name: '儿童玩具一',
text: '一个普普通通的玩具小船',
src: './images/toy1.jpeg',
quantity: 1,
money: 60.99,
subtotal: 0,
decide: false
}, {
name: '儿童玩具二',
text: '可爱的毛绒玩具',
src: './images/toy2.jpeg',
quantity: 1,
money: 58,
subtotal: 0,
decide: false
}, {
name: '儿童玩具三',
text: '趣味玩具',
src: './images/toy3.jpeg',
quantity: 1,
money: 89,
subtotal: 0,
decide: false
}],
del: false,
all: false,
fixed: false
},
methods: {
last(i) {
this.del = !this.del
},
add(i) {
if (this.Commodity[i].quantity >= 50) return
this.Commodity[i].quantity++
},
minus(i) {
if (this.Commodity[i].quantity <= 1) return
this.Commodity[i].quantity--
},
lose(i) {
if (this.Commodity[i].quantity > 50 || this.Commodity[i].quantity < 0 || this.Commodity[i].quantity === '') {
alert('数量不正确')
this.Commodity[i].quantity = 1
}
},
deleteLi(i) {
this.Commodity.splice(i, 1)
this.decideCheck('')
},
allCheck() {
this.all = !this.all
this.Commodity.forEach(p => {
p.decide = this.all
})
},
decideCheck(i) {
if (i !== '') {
this.Commodity[i].decide = !this.Commodity[i].decide
}
for (let index = 0; index < this.Commodity.length; index++) {
if (this.Commodity[index].decide === false) {
this.all = false
return
}
}
this.all = true
},
allDel() {
this.Commodity =
this.Commodity.filter(item => {
// console.log(item)
return item.decide === false
});
},
scrollToTop() {
// 获取视窗高度
let domHight = document.body.offsetHeight;
// dom滚动位置
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
// 获取窗口高度
let height = document.documentElement.clientHeight + 100
// 元素的高度
// let summarize = this.$refs.summarize.scrollTop
if (domHight <= 600) {
return
}
if (domHight < scrollTop + height) {
this.fixed = false
} else {
this.fixed = true
}
}
},
mounted() {
window.addEventListener('scroll', this.scrollToTop);
},
destroyed() {
// 跳页的时候销毁
window.removeEventListener('scroll', '')
},
computed: {
summarize() {
return this.Commodity.length
},
settle() {
let a = 0
this.Commodity.forEach(item => {
if (item.decide === true) {
a++
}
})
return a
},
allMoney() {
let money = 0
this.Commodity.forEach(item => {
if (item.decide === true) {
money = money + item.subtotal
}
})
return money
}
},
watch: {
Commodity: {
handler(newvalue, oldvalue) {
// console.log(newvalue)
if (newvalue.length > 0) {
for (let index = 0; index < newvalue.length; index++) {
newvalue[index].subtotal = newvalue[index].quantity * newvalue[index].money
}
}
},
deep: true,
immediate: true
}
}
})
发表评论 (审核通过后显示评论):