(十)實現購物車中的對商品的數量選擇操作
實現購物車中的對商品的數量選擇操作,如圖1所示,當一開始的時候,介面最右側只有一個“+”按鈕;當點選右側任意一個“+”按鈕的時候,點選的食品的相應地方會出現“-”按鈕,並且出現新增的數量,如圖2所示;當在點選其他食品的“+”按鈕的時候,也會出現點選的食品的相應地方會出現“-”按鈕,並且出現新增的數量,同時底部購物車相應的地方也會做出變化,如 圖3所示。
圖1
圖2
圖3
下面我們就詳細的講解上述聯動的效果是如何實現的。
將右側的“+”和“-”以及兩者之間的數字抽成一個元件,叫做cartControl.vue
1、cartControl.vue的<template>的內容如下,這裡用到vue中的內建元件<transition>實現過渡效果
<template> <div class="cartControl"> <!--當food.count為undefined的時候‘-’有不顯示--> <transition name="move"> <!--decreaseCart()函式在methods中定義,當點選“-”按鈕的時候,food.count減一--> <div class="cartDecrease" v-show="food.count>0" @click="decreaseCart"> <span class="inner icon-remove_circle_outline"></span> </div> </transition> <div class="cartCount" v-show="food.count>0">{{food.count}}</div> <!--addCart()在methods中定義,點選‘+’,則觸發food.count加1--> <div class="cartAdd icon-add_circle" @click="addCart"></div> </div> </template>
2、cartControl.vue的<script>內容 如下,在這裡的資料都是基於food物件,即每一種食品
<script> //這裡用到vue的一些方法 import Vue from 'vue'; export default { props:{ //購物車按鈕的控制元件是和父級元素的每一商品相關聯的 food:{ type:Object } }, methods:{ //點選food右邊的“+” addCart(event){ if( !event._constructed ){ //不是自己開發的函式,則返回,避免在pc端觸發兩次 return } if( !this.food.count ){ // 如果this.foo.count的值為undefined,表示food物件中還沒有count這個屬性 // this.food.count = 1; // set(物件,屬性,屬性值),讓手動新增的屬性,被瀏覽器識別監聽 Vue.set(this.food,'count',1); }else{ this.food.count++; } console.log(this.food.count); }, decreaseCart(event){ if( !event._constructed ){ return; } if(this.food.count){ this.food.count--; } } } } </script>
這裡有用到從父元件傳遞過來的資料food,所以要在goods.vue中引入並使用cart-control元件,在裡面繫結屬性food,下圖是goods.vue 檔案中的修改
在<script>中引入該元件並在components中註冊該元件
在<template>中引入該元件
<cart-control :food="food"></cart-control>
3、cartControl.vue中的<style>裡面的內容
<style lang="stylus">
.cartControl
font-size:0
.cartDecrease,.cartCount,.cartAdd
display:inline-block
.cartDecrease
padding:6px
opacity: 1
transform: translate3d(0, 0, 0)
.inner
display: inline-block
line-height:24px
font-size:24px
color:rgb(0,160,220)
transition: all 0.4s linear
transform: rotate(0)
&.move-enter-active,&.move-leave-active
transition: all 0.4s linear
&.move-enter, &.move-leave
opacity: 0
transform: translate3d(24px, 0, 0)
.inner
transform: rotate(180deg)
.cartCount
vertical-align: top
width:12px
padding-top:6px
line-height:24px
text-align: center
font-size:10px
color:rgb(147,153,159)
.cartAdd
padding:6px
line-height:24px
font-size:24px
color:rgb(0,160,220)
</style>
由於在子元件cartControl中有將父元件傳遞過來的food物件新增屬性count,當count在cartControl.vue中變化的時候,會自動反映到父元件goods.vue中的food
由於,要將變化的food的屬性要反映到shopCart.vue 中,所以需要對goods.vue中的<shop-cart>繫結屬性select-foods,如
<shop-cart :select-foods="selectFoods" :delivery-price="seller.deliveryPrice" :min-price="seller.minPrice"><Shop-cart>
selectFoods在goods.vue中的computed中的定義如下:
// 選中的商品,返回一個數組,陣列的成員是有count屬性的會是已經加入購物車的商品
selectFoods(){
let foods = [];
this.goods.forEach((good) => {
good.foods.forEach((food) => {
// 對每一個商品的count屬性進行遍歷
// count在cartControl.vue中有定義,會影響到父元件的
if(food.count){
// 證明該食品有新增到購物車
// 找到所有被選擇的food
foods.push(food);
}
});
});
return foods;
}
}
count屬性是在cartControl.vue中新增的,在子元件對父元件傳遞過來的資料的修改會反映到父元件上面,所以在父元件可以對每一樣good下面的每一樣的food遍歷,當food下面有count屬性的時候,說面該food已經被新增到購物車了在shopCart.vue中需要對屬性select-foods做宣告:
注意: 在父元件good.vue中繫結屬性用橫劃線的寫法select-foods,而在s子元件shopCart.vue中宣告該屬性的時候,用的是駝峰寫法selectFoods