08、Vue-Food组件(商品详情)《饿了吗》
2017-07-27 本文已影响138人
EndEvent
一、阻止事件冒泡
当点击商品列表跳转到详情时,添加商品(移除商品)都会触发到该事件,即需要阻止事件的冒泡
@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后,才重新计算高度!!!