美文网首页
08、Vue-Food组件(商品详情)《饿了吗》

08、Vue-Food组件(商品详情)《饿了吗》

作者: 王梓懿_1fbc | 来源:发表于2018-10-20 16:31 被阅读4次

    一、阻止事件冒泡

    当点击商品列表跳转到详情时,添加商品(移除商品)都会触发到该事件,即需要阻止事件的冒泡

    @click.stop.prevent="addCart($event)"  // 阻止事件冒泡
    

    二、评论选择组件

    • 需要接收的参数
      Food父组件中,将参数传递给Ratingselect子组件
        props: {
            selecttype: {       // 选择类型(全部/满意/不满意)
                type: Number,
                default: ALL
            },
            onlycontent: {      // 只看有内容的
                type: Boolean,
                default: false 
            },
            desc: {             // 选项的显示内容
                type: Object,
                default() {    // 默认值
                    return {
                        all: '全部',
                        satisfied: '满意',
                        dissatisfied: '不满意'
                    }
                }
            },
            ratings: {    // 评论数据
                type: Array
            }
        },
    
    • 选择的内容传递回父组件
      Ratingselect子组件选择后,将对应的数据传递会Food父组(因为是值类型,所以需要传递回去,如果是引用类型即不需要)
    selectFn(type,event) {  // 全部、满意、不满意
        if(!event._constructed) {
          return;
        }
        // 自定义事件
        this.$emit('ratingtype-select', this.selecttype);
    },
    toggleContent(event){  // 只看有内容的(true、false)
        if(!event._constructed) {
          return;
        }
        this.onlycontent = !this.onlycontent;
        // 自定义事件
        this.$emit('content-toggle', this.onlycontent);
    }
    

    三、评论组件

    • 评论页面的显示
      父组件Goods,通过调用子组件Food中的showView方法来控制页面商品详情页的显示或隐藏
      // Food.vue
      <div class="food" v-if='isShow' ref='foodScroll'></div>
    
      showView() {  // 显示详情页
        this.isShow = true;
      },
      closeView(event){  // 隐藏详情页
        if(!event._constructed) {
          return
        }
       this.isShow = false;
      }
      // Goods.vue
      <food :food='selectFood' ref='foodDetail'></food>
    
      // 获取到对应组件,并调用对应方法
      showFoodDetail(food,event) {
        if(!event._constructed){  // pc端的不做任何处理
          return
        }   
        this.selectFood = food;
        // 调用food组件的显示方法
        this.$refs.foodDetail.showView();
      }
    
    • 时间的格式化操作
    <div class="time">{{formatDate(rating.rateTime)}}</div>
    
      export default {
        methods: {
            formatDate(time) {
                // 时间格式
                var fmt = 'yyyy-MM-dd hh:mm'
                // 转为Date对象
                var date = new Date(time);
            
                // 正则匹配,并替换
                if(/(y+)/.test(fmt)) { // 年
                    // RegExp.$1获取到正则对应的第一个元素yyyy
                    var year = date.getFullYear() + '';
                    fmt = fmt.replace(RegExp.$1, year);
                }
                if(/(M+)/.test(fmt)) { // 月
                    var month = date.getMonth() + 1;
                    if(month < 10) {
                        month = '0' + month;
                    }
                    fmt = fmt.replace(RegExp.$1, month);
                }
                if(/(d+)/.test(fmt)) { // 日
                    var mydate = date.getDate() + '';
                    if(mydate < 10) {
                        mydate = '0' + mydate;
                    }
                    fmt = fmt.replace(RegExp.$1, mydate);
                }
                if(/(h+)/.test(fmt)) { // 时
                    var hours = date.getHours() + '';
                    if(hours < 10) {
                        hours = '0' + hours;
                    }
                    fmt = fmt.replace(RegExp.$1, hours);
                }
                if(/(m+)/.test(fmt)) { // 分
                    var minu = date.getMinutes() + '';
                    if(minu < 10) {
                        minu = '0' + minu;
                    }
                    fmt = fmt.replace(RegExp.$1, minu);
                }
            
                return fmt;
            },
        },
        // ...
      }
    
    • 评论的过滤
      评论可以选择显示全部、满意、不满意、显示有内容的选项,所以需要对数据进行过滤操作
    // 通过v-show来达到评论的显示或隐藏(数据过滤)
    <li v-show='needShow(rating.rateType, rating.text)' v-for="rating in food.ratings" class="rating-item">
      // ...
    </li>
    
      needShow(rateType, ratingText) {
        // 只看显示内容true && 有内容true   (跳过)
        // 只看显示内容true && 没内容false   即false(显示有内容,但却没内容)
        // 只看有内容false 直接跳过
        if(this.onlycontent && !ratingText){
          return false;
        }
                    
        if(this.selecttype === ALL){    // 显示所有
          return true;
        } else {        // 类型和选择的相符合即true
          return rateType===this.selecttype;
        }
      },
    
    • 接收到不同选项时
      通过自定义事件,接收到Ratingselect组件回传的数据,更改data对应数据选项,之后再更新滚动高度
      ratingtypeSelect(type) {  
        this.selecttype = type;
        this.$nextTick(()=>{        // 
            this.foodScroll.refresh();
        })
      },
      contentToggle(onlycontent) {
        this.onlycontent = onlycontent;
        this.$nextTick(()=>{
            this.foodScroll.refresh();
        })
    }
    

    注意: 接收到对应选项,会根据选项进行数据过滤,此时要更新DOM后,才重新计算高度!!!

    作者:西门奄
    链接:https://www.jianshu.com/u/77035eb804c3
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

    相关文章

      网友评论

          本文标题:08、Vue-Food组件(商品详情)《饿了吗》

          本文链接:https://www.haomeiwen.com/subject/glsmzftx.html