VUE2.0 饿了么学习笔记(10)加减号组件cartcontrol

建立cartcontrol组件,组件关联到food的相关属性,价格,数量等,因此组件要props父组件goods传过来的food数据javascript

export default {
    //父组件传过来的,接收一个props属性来计算商品的个数,food.count,去goods组件中引入cartcontrol
    props: {
        food: {
            type: Object
        }
    }

布局:分三层,减小,数量num,增长,food.count>0时才会出现减小和数量的divcss

<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传入html

<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添加样式,将其固定在右侧vue

.cartcontrol-wrapper
            position absolute
            right 0
            bottom 24px

在加减号组件中created中logs一下food,看是否能正确拿到food的值java

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

接下来给cartContronl写样式,简单的样式,没有添加动画json

以后在,加号部分添加一个点击事件,点击以后,改变food.count的值浏览器

<div class="cart-add icon-add_circle" @click.stop.prevent="addCart"></div> <!-- 加号图标 -->

由于goods组件中用了betterScroll组件,因此咱们在点击goods组件图层上的加减号组件时,不要忘了在初始化滚动组件的时候为其添加click:true容许点击app

在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>

 

以后,为加减号添加动画小球的特效