1. 程式人生 > >(十)實現購物車中的對商品的數量選擇操作

(十)實現購物車中的對商品的數量選擇操作

實現購物車中的對商品的數量選擇操作,如圖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