vuejs2-7评价页面
1 src/components/ratings/ratings.vue
<template>
<div class="ratings" ref="ratings">
<div class="rating-content">
<div class="overview">
<div class="overview-left">
<h2 class="scoer">{{seller.score}}</h2>
<div class="title">综合评分</div>
<div class="rank">高于周边商家{{seller.rankRate}}%</div>
</div>
<div class="overview-right">
<p class="score-wrapper">
<span class="title">服务态度</span>
<star :size="36" :score="seller.serviceScore"></star>
<span class="score">{{seller.serviceScore}}</span>
</p>
<p class="score-wrapper">
<span class="title">商品评分</span>
<star :size="36" :score="seller.foodScore"></star>
<span class="score">{{seller.foodScore}}</span>
</p>
<p class="delivery-wrapper">
<span class="title">送达时间</span>
<span class="delivery">{{seller.deliveryTime}}</span>
<span class="time">分钟</span>
</p>
</div>
</div>
<ratingselect @select="selectRating" @toggle="toggleContent" :selectType="selectType" :onlyContent="onlyContent" :desc="desc" :ratings="ratings"></ratingselect>
<!--评论列表-->
<div class="rating-wrapper">
<ul>
<li v-for="rating in ratings" class="rating-item" v-show="needShow(rating.rateType,rating.text)">
<div class="avatar"><img :src="rating.avatar" alt="" width="28" height="28"></div>
<div class="content">
<h2 class="name">{{rating.username}}</h2>
<div class="star-wrapper">
<star :size="24" :score="rating.score"></star>
<span class="delivery" v-show="rating.deliveryTime">{{rating.deliveryTime}}分钟到达</span>
</div>
<p class="text">{{rating.text}}</p>
<div class="recommend" v-show="rating.recommend && rating.recommend.length">
<span class="icon-thumb_up"></span>
<span v-for="item in rating.recommend" class="item">{{item}}</span>
</div>
<div class="time">{{rating.rateTime | formatDate}}</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</template>
<script type="text/ecmascript-6">
import star from 'components/star/star';
import BScroll from 'better-scroll';
import split from 'components/split/split';
import ratingselect from 'components/ratingselect/ratingselect';
import {formatDate} from 'common/js/date';
const ALL = 2;
const ERR_OK = 0;
export default{
props: {
seller: { // 获取路由组件(app.vue)传递过来的数据
type: Object
}
},
data() {
return {
ratings: [],
selectType: ALL,
onlyContent: true,
desc: {
all: '全部',
positive: '满意',
negative: '不满意'
}
};
},
created() {
this.$http.get('/api/ratings').then((res) => {
res = res.body;
if (res.errno === ERR_OK) {
this.ratings = res.data;
this.$nextTick(() => {
this.scroll = new BScroll(this.$refs.ratings, {
click: true
});
});
};
});
},
filters: {
formatDate(time) {
let date = new Date(time);
return formatDate(date, 'yyyy-MM-dd hh:mm');
}
},
methods: {
needShow(type, text) { // 对ratingselect.vue组件的改变做处理
if (this.onlyContent && !text) { // 只有内容没有文本时
return false;
};
if (this.selectType === ALL) {
return true;
} else {
return type === this.selectType;
}
},
selectRating(type) { //
this.selectType = type; // ratingselect.vue改变父组件的值
this.$nextTick(() => {
this.scroll.refresh(); // 解决去掉勾选后bs可拖动范围问题
});
},
toggleContent() {
this.onlyContent = !this.onlyContent;
this.$nextTick(() => {
this.scroll.refresh();
});
}
},
components: {
star: star,
split: split,
ratingselect: ratingselect
}
};
</script>
<style lang="stylus" rel="stylesheet/stylus">
.ratings
position:absolute
top:174px
bottom:0px
left:0
width:100%
overflow:hidden
.overview
display:flex
padding:18px 0
.overview-left
flex:0 0 137px
width:137px
padding:6px 0
border-right:1px solid rgba(7,17,27,0.1)
text-align:center
/*@media only screen add ( max-width: 320px )
flex:0 0 120px
width:120px*/
.score
font-size:24px
color:rgb(255,153,0)
line-height:28px
.title
font-size:12px
color:rgb(7,17,27)
line-height:12px
font-weight:700
margin-top:6px
margin-bottom:8px
.rank
font-size:10px
color:rgb(147,153,159)
line-height:10px
.overview-right
flex:1
padding:6px 19px 0
/*@media only screen add ( max-width: 320px )
padding-left:6px*/
.score-wrapper
margin-bottom:8px
font-size:0
.title
font-size:12px
color:rgb(7,17,27)
vertical-align:top
line-height:18px
.star
display:inline-block
margin:0 12px
vertical-align:top
.score
display:inline-block
font-size:12px
vertical-align:top
color:rgb(255,153,0)
line-height:18px
.delivery-wrapper
font-size:0
.title
font-size:12px
color:rgb(7,17,27)
line-height:18px
.delivery
font-size:12px
color:rgb(147,153,159)
margin-left:12px
.time
display:inline-block
font-size:12px
color:rgb(147,153,159)
.rating-wrapper
.rating-item
border-bottom:1px solid rgba(7,17,27,0.1)
display:flex
font-size:0
margin:0 16px
padding:16px 0
.avatar
flex:0 0 28px
width:28px
height:28px
margin-right:12px
img
border-radius:50%
.content
flex:1
position:relative
.name
line-height:12px
font-size:10px
color:rgb(7,17,27)
margin-bottom:4px
.star-wrapper
font-size:0
margin-bottom:6px
.star
display:inline-block
margin-right:6px
viertical-align:top
.delivery
display:inline-block
viertical-align:top
line-height:12px
font-size:10px
color:rgb(147,153,159)
.text
font-size:12px
color:rgb(147,153,159)
font-weight:200
margin-bottom:8px
.recommend
font-size:0px
line-height:16px
.icon-thumb_up
display:inline-block
margin:0 8px 4px 0
font-size:9px
color:rgb(0,160,220)
.item
display:inline-block
font-size:9px
padding:0 6px
border:1px solid rgba(7,17,27,0.1)
border-radius:1px
background-color:#fff
margin-right:8px
.time
position:absolute
top:0
right:0
font-size:10px
font-weight:200
color:rgb(147,153,159)
line-height:12px
</style>
2 src/components/ratingselect/ratingselect.vue
<template>
<div class="ratingselect">
<div class="rating-type border-1px">
<span class="block positive" :class="{active:selectType===2}" @click="select(2,$event)">{{desc.all}}<span class="count">{{ratings.length}}</span></span>
<span class="block positive" :class="{active:selectType===0}" @click="select(0,$event)">{{desc.positive}}<span class="count">{{positives.length}}</span></span>
<span class="block negative" :class="{active:selectType===1}" @click="select(1,$event)">{{desc.negative}}<span class="count">{{negatives.length}}</span></span>
</div>
<div class="switch" :class="{on:onlyContent}" @click="toggleContent">
<i class="icon-check_circle"></i>
<span class="text">只看有评价的内容</span>
</div>
</div>
</template>
<script type="text/ecmascript-6">
const POSITIVE = 0;
const NEGATIVE = 1;
const ALL = 2;
export default {
props: {
ratings: {
type: Array,
default() {
return [];
}
},
selectType: { // 接收 ratings.vue传递的 :selectType="selectType"
type: Number,
default: ALL
},
onlyContent: { // 接收 ratings.vue传递的 :onlyContent="onlyContent"
type: Boolean,
default: false // 默认可以看到所有评论
},
desc: {
type: Object,
default() { // 默认文字显示
return {
all: '全部',
positive: '满意',
negative: '不满意'
};
}
}
},
methods: {
select(type, ev) { // 选择全部 满意 不满意
if (!ev._constructed) { // 使用了BS
return;
};
this.$emit('select', type); // 将selectType变化的值交给父组件ratings.vue处理(改变selectType的值)
},
toggleContent(ev) { // 点击了只看有评价的内容
if (!ev._constructed) { // 使用了BS
return;
};
this.$emit('toggle'); //
}
},
computed: {
positives() { // 推荐数量
return this.ratings.filter((rating) => {
return rating.rateType === POSITIVE;
});
},
negatives() { // 不满意数量
return this.ratings.filter((rating) => {
return rating.rateType === NEGATIVE;
});
}
}
};
</script>
<style lang="stylus" rel="stylesheet/stylus">
@import "../../common/stylus/mixin.styl"
.ratingselect
.rating-type
padding:18px 0
margin:0 18px
border-1px(rgba(7,17,27,0.1))
font-size:0px
.block
display:inline-block
padding:8px 12px
border-radius:1px
margin-right:8px
color:rgb(77,85,93)
font-size:12px
line-height:16px
&.active
color:#fff
.count
font-size:8px
margin-left:2px
&.positive
background: rgba(0,160,220,0.2)
&.active
background:rgb(0,160,220)
&.negative
background-color:rgba(77,85,93,0.2)
&.active
background-color:rgb(77,85,93)
.switch
padding:12px 18px
line-height:24px
border-bottom:1px solid rgba(7,17,27,0.1)
color:rgb(147,153,159)
font-size:0
&.on
.icon-check_circle
color:#00c850
.icon-check_circle
display:inline-block;
vertical-align:middle
font-size:24px
margin-right: 4px
.text
font-size:12px
display:inline-block
vertical-align:middle
</style>
3 简单图解


浙公网安备 33010602011771号