vuejs仿美团,饿了么项目之——购物车篇
2018-07-27 本文已影响0人
从小就很瘦
上一篇写了个商品加减的组件,这篇说一下购物车。只有当添加商品的时候,也就是存在count这个key的时候,购物车的样式才改变,计算属性总价格,总数量才实现。所以我们先在good.vue中判断下此时是否点击了添加商品事件,也就是判断是否有count;
我写的本地的json数据是类似这样的:
{
"data": {
"food":[
{
"name":"饮料",
"detail": [
{
"name": "芬达",
"price": 3
},
{
"name": "可乐",
"price": 4
},
{
"name": "雪碧",
"price": 5
}
]
},
{
"name":"水果",
"detail": [
{
"name": "香蕉",
"price": 3
},
{
"name": "西瓜",
"price": 4
},
在计算属性中:
checkCount(){
let foodlist = [];
this.food.forEach(val => {
val.detail.forEach(val => {
if(val.count){
foodlist.push(val)
}
})
})
return foodlist;
},
data中的food数组已经获取了数据中的food,所以在checkCount()中如果有count,那么就用foodlist数组存储food.detail,也就是商品的有关数据。然后在组件中通过props传给子组件shopcart。
下面就简单了,子组件获取数据之后,判断如果有count,说明添加商品的事件被触发,那么就在computed写2个方法,计算总价格和总数量。同时用v-show来控制css样式。
详细代码如下:
<template>
<div class="shopcart">
<div class="left">
<div class="circle" :class="{'highlight': totalCount}">
<div class="num-red" v-show="totalCount">
{{totalCount}}
</div>
</div>
<div class="left-text-before" v-show="!totalCount">
{{check.trackingBefore}}
</div>
<div class="left-text-after" v-show="totalCount">
<div class="total-money">
¥{{totalMoney}}
</div>
<div class="tracking">
{{check.trackingBefore}}
</div>
</div>
</div>
<div class="right" :class="{'highlight': totalCount}">
{{checkAll}}
</div>
</div>
</template>
<script>
export default {
data() {
return {
check: {
trackingBefore:'另需配送费¥5',
checkBefore: '¥20起送',
checkAfter: '去结算',
},
}
},
props: {
foodlist:{
type: Array
}
},
methods: {
},
computed: {
totalMoney(){
let total = 0;
this.foodlist.forEach(val => {
if(!val.count){
return
}else{
total += val.count*val.price
}
})
return total
},
totalCount(){
let num = 0;
this.foodlist.forEach(val => {
if(!val.count){
return
}else{
num += val.count
}
})
return num
},
checkAll(){
if(this.totalCount){
return this.check.checkAfter
}else{
return this.check.checkBefore
}
}
}
}
</script>
<style>
.shopcart {
width: 100%;
background: #514f4f;
position: fixed;
bottom: 0;
height: 50px;
display: flex;
}
.left{
flex:1;
}
.circle {
width: 50px;
height: 50px;
background: #726d6d;
border-radius: 50%;
position: relative;
left: 10px;
bottom: 16px;
float: left;
}
.circle .num-red {
position: absolute;
width: 15px;
height: 15px;
border-radius: 50%;
background: red;
color: white;
font-size: 9px;
line-height: 15px;
text-align: center;
right: 0;
top: 0;
}
.left-text-before{
position: relative;
left: 18px;
font-size: 14px;
line-height: 50px;
color: #c4c4c4;
float: left;
}
.left-text-after {
position: relative;
left: 18px;
color: #c4c4c4;
float: left;
}
.left-text-after .total-money {
font-size: 24px;
line-height: 28px;
}
.left-text-after .tracking {
font-size: 11px;
margin-top: 3px;
}
.right {
flex: 0 0 110px;
line-height: 50px;
text-align: center;
color:#c4c4c4;
}
.highlight {
background: #FFD161;
color: #2D2B2A;
}
</style>
那么菜单上如何同步红色数量的显示呢?
在good.vue中,红色数量DOM结构如下
<li ref="menuItem" class="menu-item" :class="{'current': currentIndex == index}" @click="selectIndex(index)" v-for="(item, index) in food">
{{item.name}}
<div class="num-red" v-show="redNum(item.detail)">
{{redNum(item.detail)}}
</div>
</li>
在methods中,detail参数来接受传入的item,detail,也就是JSON数据中的detail数组。首先要判断数组是否存在,否则可能报错,如果存在,那么遍历对象,获取各个商品的count赋值给num,return num
redNum(detail){
if(detail){
let num = 0
detail.forEach(val => {
if(val.count){
num += val.count
}
})
return num
}
}
这样就实现了,点击添加商品,底部购物车显示商品总价和数量,样式改变,左侧菜单也会有商品数量的显示。效果如下:
Animation.gif
只因为count的改变,从而改变了好多东西,充分体现了vue数据操控模型的魅力所在。
好,下篇写一下关于购物车列表的功能。