vue2.0 饿了么学习笔记(14)food.vue的实现

点击food展开详情页food.vue的实现

1)新建good文件夹和good.vue,设置样式,并接受一个被选中的food

 props: { //接收传入的food
        food: {
            type: Object
        }
    }
2)获取food数据,goods.vue中

food是由goods组件传出的,现在goods组件中引入food,并从data中将被选中的food传入food.vue中

<food :food="selectedFood"></food>

其中,selectedFood初始化为空对象,一开始没有food被选择

data{
	 selectedFood: {} //一开始是空对象,点击food的时候再存入,在li(food)中添加点击事件
 }

之后在goos.vue的food列表中添加点击事件,点击food之后,更新selectedFood{}

<li @click="selectFood(food,$event)" v-for="food in item.foods" :key="food.id" class="food-item"  border-1px>
 <li @click="selectFood(food,$event)" v-for="food in item.foods" :key="food.id" class="food-item"  border-1px>
 selectFood(food, event){ //@click函数
    if (!event._constructed) { //浏览器直接return掉,去掉自带click事件的点击
        return;
     }
      this.selectedFood = food; //更新data中的selectedFood
  }

最后,如1),在food.vue中接收food数据

3)在goods.vue中,点击一种food的时候会弹出food.vue中的详情界面,添加this.$refs.food.show();

  <li v-for="food in item.foods" :key="food.id" class="food-item" border-1px @click="selectFood(food,$event)">

selectFood(food, event) { //@click函数
    if (!event._constructed) { //浏览器直接return掉,去掉自带click事件的点击
        return;
     }
      this.selectedFood = food;
      //调用子组件的show()方法展开food组件
      this.$refs.food.show();
  }
 },

在food.vue中添加show()方法

    show() { //可以被父组件调用到,方法前加下划线一般是私有方法
            this.showFlag = true;
            //初始化部分,ratingselect组件是被被不同的商品使用的,所以我们希望在点开不同的商品时,能有一样的初始化状态
            this.selectType = ALL;
            this.onlyContent = false;
            //展示界面时用到BScroll
            this.$nextTick(() => {
                if (!this.scroll) {
                    this.scroll = new BScroll(this.$refs.food, {
                        click: true // 可以被点击
                    });
                } else {
                   this.scroll.refresh();
                }
            });
        },
4)布局food页面,添加图片,并为图片左上角添加返回按钮
    <div class="image-header">
       <img :src="food.image" alt="">
       <div class="back" @click="hide">
           <i class="icon-arrow_lift"></i>
        </div>
     </div>
        hide() {
            this.showFlag = false;
        },
<div v-show="showFlag" class="food" ref="food"> 实际上改变的是show方法中showFlage的值

5)添加商品名称,月售价格等部分+CSS布局

扫描二维码关注公众号,回复: 2249079 查看本文章

6) good.vue是定长的,我们希望添加BScroll实现滚动布局,将BScroll绑定在最外层,为其添加ref,让其DOM可以被访问到,BScroll应该在界面呈现时用到,将其添加到show()方法(界面呈现)中

good.vue中
	show() { //可以被父组件调用到,方法前加下划线一般是私有方法
            this.showFlag = true;
            //ratingselect组件是被被不同的商品使用的,所以我们希望在点开不同的商品时,能有一样的初始化状态
            this.selectType = ALL;
            this.onlyContent = true;
            //展示界面时用到BScroll
            this.$nextTick(() => {
                if (!this.scroll) {
                    this.scroll = new BScroll(this.$refs.food, {
                        click: true // 可以被点击
                    });
                } else {
                   this.scroll.refresh();
                }
            });
        },
food.vue中
 selectFood(food, event) { //@click函数
    if (!event._constructed) { //浏览器直接return掉,去掉自带click事件的点击
        return;
     }
      this.selectedFood = food;
      //调用子组件的show()方法展开food组件
      this.$refs.food.show();
  }

7)添加加入购物车按钮,点击加入购物车之后,出现cartcontrol加减号按钮

 <div class="cartcontrol-wrapper"> <!-- 加减号组件cartcontrol -->
        <cartcontrol :food="food"></cartcontrol>
  </div>
                <transition name="fade"> 
                    <div @click.stop.prevent="addFirst" class="buy" v-show="food.count === 0 || !food.count">
                        加入购物车    
                    </div> <!-- 这两种情况下加入购物车都会显示,否则就会隐藏-->
                </transition>
1.当food.count=0或者是不存在food.count(没有在goods.vue界面被点击过的情况)时,才会出现添加购物车字样,否则显示cartcontrol加减号组件

2.点击了加入购物车按钮之后,出发addFirst()事件,即第一次添加事件,这是加入购物车字样转变为加减号组件

        addFirst(event) { // 默认的参数是event,点击按钮的时候添加的是第一个商品
            if (!event._constructed) { //浏览器直接return掉,去掉自带click事件的点击
                return;
            }
            //第一次的时候el消失,找不到小球发出的其实位置,所以第一次小球动画消失
            //解决办法就是将购物车的消失做成一个动画,而不是立马display:none
            //添加的时候添加小球动画,派发事件,之后goods.vue就可以监听到cart-add,并传递给shopcart.vue
            this.$emit('cart-add', event.target);
            Vue.set(this.food, 'count', 1); //初始化this.food.count = 1;
        }

3.父组件goods.vue中进行监听

 cartAdd(target) {
     //拿到traget(DOM对象)之后,将其传入shopcart组件中drop(target){}方法,
     //此处用this.$refs调用子组件,访问DOM时用的是ref="menuWrapper"
    this.$nextTick(() => { //回调函数异步执行,两个动画效果就不会卡顿了
      this.$refs.shopcart.drop(target);
    });
   },
      <div class="cartcontrol-wrapper">
          <cartcontrol v-on:cart-add="cartAdd" :food="food"></cartcontrol> <!-- 传入food!!!-->
      </div>
CSS:
.cartcontrol-wrapper
        position absolute
        right 12px
        bottom 12px
    .buy
        position absolute
        right 18px
        bottom 18px
        z-index 10 // 要盖住加减号组件
        height 24px
        line-height 24px
        padding 0 12px
        box-sizing border-box
        font-size 10px
        border-radius 10px
        color #ffffff
        background rgb(0,160,220)
        &.fade-enter-active, &.fade-leave-active
            transition all 0.2s 
            opacity 1
        &.fade-enter, &fade-leave-active
            opacity 0

8)在goods组件点击加减号cartcontrol的时候,也会引起good详情页的出现,此时在cartcontrol中阻止加减号的冒泡即可,同时对加入购物车的click也设置阻止冒泡

<div class="cart-decrease" v-show="food.count>0" @click.stop.prevent="decreaseCart">
<div class="cart-add icon-add_circle" @click.stop.prevent="addCart"></div>
<div @click.stop.prevent="addFirst" class="buy" v-show="food.count === 0 || !food.count">
9)split组件的实现(多次出现的一个分割样式,将其抽象为组件)
<template>
  <div class="split"></div>
</template>

<script type="text/ecmascript-6">
  export default {};
</script>

<style lang="stylus" rel="stylesheet/stylus">
    .split
        width 100%
        height 16px
        border-top: 1px solid rgba(1, 17, 27, 0.1);
        border-bottom: 1px solid rgba(1, 17, 27, 0.1);
        background: #f3f5f7
</style>
在food.vue引入注册之后就可以使用了

猜你喜欢

转载自blog.csdn.net/qq_22317389/article/details/80459018