1. 程式人生 > >VUE2.0 餓了麼學習筆記(10)加減號元件cartcontrol

VUE2.0 餓了麼學習筆記(10)加減號元件cartcontrol

建立cartcontrol元件,元件關聯到food的相關屬性,價格,數量等,所以元件要props父元件goods傳過來的food資料

export default {
    //父元件傳過來的,接收一個props屬性來計算商品的個數,food.count,去goods元件中引入cartcontrol
    props: {
        food: {
            type: Object
        }
    }

佈局:分三層,減少,數量num,增加,food.count>0時才會出現減少和數量的div

 <div class="cartcontrol">
        <transition name="fade"> <!-- 外層漸變,減號圖示-->
            <div class="cart-decrease" v-show="food.count>0" @click.stop.prevent="decreaseCart">
                <transition name="inner"> <!-- 內層滾動,滾動時包含字型,字型在inner中-->
                    <span class="inner icon-remove_circle_outline"></span>
                </transition>
            </div>
        </transition>
        <div class="cart-count" v-show="food.count > 0">{{food.count}}</div>
        <div class="cart-add icon-add_circle" @click.stop.prevent="addCart"></div> <!-- 加號圖示 -->
    </div>

在goods中引入並註冊元件,然後在模板裡應用元件,每個food的下邊都有一個加減號元件,元件應包含在content中,即在價格的右邊,並將food傳入

    <div class="price">
                 <span class="now">¥{{food.price}}</span><span class="old" v-show="food.oldPrice">¥{{food.oldPrice}}</span>
               </div>
               <div class="cartcontrol-wrapper">
                <cartcontrol v-on:cart-add="cartAdd" :food="food"></cartcontrol> <!-- 傳入food!!!-->
               </div>

併為cartcontrol-wrapper新增樣式,將其固定在右側

        .cartcontrol-wrapper
            position absolute
            right 0
            bottom 24px     

在加減號元件中created中logs一下food,看是否能正確拿到food的值

 created() {
       // console.log(this.food); //忘記加this
    }

接下來給cartContronl寫樣式,簡單的樣式,沒有新增動畫

之後在,加號部分新增一個點選事件,點選之後,改變food.count的值

<div class="cart-add icon-add_circle" @click.stop.prevent="addCart"></div> <!-- 加號圖示 -->

因為goods元件中用了betterScroll元件,所以我們在點選goods元件圖層上的加減號元件時,不要忘了在初始化滾動元件的時候為其新增click:true允許點選

在goods中初始化時:

     this.foodsScroll = new BScroll(this.$refs.foodsWrapper, {
       click: true,
       probeType: 3 //BScroll滾動時,能實時告訴我們滾動的位置,類似探針的效果
     });
    addCart(event) { 
            //解決PC端雙點選的問題
            if (!event._constructed) { //瀏覽器直接return掉,去掉自帶click事件的點選
                return;
            }
            //console.log('click');//點選不生效,不要忘了在foodScroll中新增click: true 
            if (!this.food.count) {
                 //food.count是原json中不存在的屬性,不能直接新增
                //this.food.count = 1;
                Vue.set(this.food, 'count', 1);//給this.food增加一個count屬性,並初始化為1
            } else {
                this.food.count++;
            }
        }

我們發現我們新增的約束條件當food.count>0時,並沒有出現數字和減號,這是因為count是food中不存在的屬性,propty檢測不到屬性的變化, 我們要為其新增count這個屬性

import Vue from 'vue';

 Vue.set(this.food, 'count', 1);//給this.food增加一個count屬性,並初始化為1

給count新增css屬性之後,count即可出現,而且我們可以利用padding增加按鈕的點選區域

        .cart-count
            display inline-block
            vertical-align top
            width 12px
            padding-top 8px
            line-height 24px
            text-align center 
            font-size 16px
            color rgb(147,153,159)

為減號新增一個點選事件

<div class="cart-decrease" v-show="food.count>0" @click.stop.prevent="decreaseCart">
    decreaseCart(event) {
            //解決PC端雙點選的問題
            if (!event._constructed) { //瀏覽器直接return掉,去掉自帶click事件的點選
                return;
            }
            if (this.food.count) {
                this.food.count--;
            }
        }

最後,為加減號新增滾動的動畫,點選加號的時候減號的按鈕時從右到左滾動過來的,這樣就有兩個動畫平移加滾動,還需要一個透明度從0到1的一個漸變過程,所以減元件需要兩個層級,外層負責平移,內層負責滾動,表示字型的層應該放到內層

        <transition name="fade"> <!-- 外層漸變,減號圖示-->
            <div class="cart-decrease" v-show="food.count>0" @click.stop.prevent="decreaseCart">
                <transition name="inner"> <!-- 內層滾動,滾動時包含字型,字型在inner中-->
                    <span class="inner icon-remove_circle_outline"></span>
                </transition>
            </div>
        </transition>
    .cartcontrol
        font-size 0 // 消除incline-block中的空隙
        .cart-decrease, .cart-add
            display inline-block // 橫向排列
            padding 6px // 圖示較小,增加它的點選區域
            &.fade-enter-active, &.fade-leave-active //進入動畫的狀態/離開動畫時生效
                transition: all 0.4s linear
                opacity 1
                transform translate3d(0, 0, 0)
            &.fade-enter, &.fade-leave-active //動畫的開始狀態,動畫一開始透明度要設為0/離開動畫的結束狀態
                opacity: 0
                transform translate3d(24px, 0, 0)
            .inner
                display inline-block //有寬高
                line-height 24px
                font-size 24px
                vertical-align top
                color rgb(0, 160, 220, 0.2)
                &.inner-enter-active, &.inner-leave-active 
                    transition: all 0.4s linear
                    opacity 1
                    transform: rotate(0)
                &.inner-enter, &.inner-leave-active 
                    opacity: 0
                    transform  rotate(180deg)

我們通過加減號元件修改了food的count屬性,要將count的變化通知其父元件goods,然後goods通過計算得出selectFoods的變化,通知到購物車元件

首先在goods.vue中編寫selectFoods,selectFoods元件要遍歷所有的goods(計算屬性),selectFood是一個計算屬性,它觀測的就是就是goods物件,goods發生變化他會重新計算進行更新

//用data繫結goods,以便後續新增到DOM中
data() {
  return {
    goods: [],
    listHeight: [], //儲存區塊的高度
  };
}
  selectFoods() { //遍歷foods,看看選中了哪些商品
    let foods = [];
    this.goods.forEach((good) => { //先取到每一個分類
      good.foods.forEach((food) => { //後取到每一個分類下的不同food
        if (food.count) {
          foods.push(food); //兩層遍歷,取到所有被選中的foods
        }
      });
    });
    return foods; //將結果傳回到shopcart
   }
}

再將selectFoods的結果傳遞到cartcontrol(購物車)元件中,這樣,在點選加減號時改變了food的count屬性,count的變化傳回到父元件,然後在父元件中遍歷goods下的foods,就取到了所有被選中的foods,將其返回值傳遞到shopCart中,就完成了加減號與購物車的同步聯動

  <shopcart ref="shopcart" :select-foods="selectFoods" :delivery-price="seller.deliveryPrice" :min-price="seller.minPrice"></shopcart>

之後,為加減號新增動畫小球的特效