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

一、阻止事件冒泡

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

@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
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Blocks是C语言的扩充功能。 用一句话来概括就是:带有自动变量(局部变量)的匿名函数。 在其他语言中Block...
    呉囲仌犮yzx阅读 293评论 0 1
  • 江城子 - 杏花歌 笙歌夺色春意深, 夜玲珑, 月近人。 点点花阴, 莳香润瑶琴。 花前斗酒第一尊, 谁为我, 醉...
    钱塘小泥鳅阅读 258评论 0 1