一、前言
二、主要內容
1、效果分析
2、分析
1)根據上面的兩部分的條件需要得到計算之后的新數組
2)評論的數據參數如下
滿意的時候rateType=0:
不滿意的時候rateType=1
(3)條件1:當選擇 “全部” 的時候,不需要考慮“滿意”,“不滿意”這兩個
(4)條件2:考慮此時是“勾選” 還是 “不勾選”狀態
(5)綜合上面兩個條件,取交集
3、具體實現
1)我們需要從vuex中得到ratings(評論的數組),
data () { return { onlyShowText: true, // 是否只顯示有文本的 selectType: 2 , // 選擇的評價類型: 0滿意, 1不滿意, 2全部 } }, mounted () { this.$store.dispatch('getShopRatings', () => { this.$nextTick(() => { new BScroll(this.$refs.ratings, { click: true }) }) }) }, computed: { ...mapState(['ratings']), //獲取到評論數組 filterRatings () { //過濾數組 const {onlyShowText, selectType, ratings} = this return this.ratings.filter(rating=>{ const {text, rateType} = rating //分析: /*條件1: 1)先判斷selectType是否為2,如果為2,不需考慮下面了 2) selectType!=2, 就考慮當前評論的 rateType==selectType 總結: selectType==2 || selectType == rateType */ /*條件2: 1)看onlyShowText ==false不選中,不需要考慮后面了 2)選中看評論的text是否大於0 */ return (selectType==2 || selectType == rateType)&& (!onlyShowText || text.length>0) }) } }, methods: { setSelectType (selectType) { this.selectType = selectType }, toggleOnlyShowText () { this.onlyShowText = !this.onlyShowText } },
4、完整代碼

<template> <div class="ratings" ref="ratings"> <div class="ratings-content"> <div class="overview"> <div class="overview-left"> <h1 class="score">{{info.score}}</h1> <div class="title">綜合評分</div> <div class="rank">高於周邊商家99%</div> </div> <div class="overview-right"> <div class="score-wrapper"> <span class="title">服務態度</span> <Star :score="info.serviceScore" :size="36" /> <span class="score">{{info.serviceScore}}</span> </div> <div class="score-wrapper"> <span class="title">商品評分</span> <Star :score="info.foodScore" :size="36" /> <span class="score">{{info.foodScore}}</span> </div> <div class="delivery-wrapper"> <span class="title">送達時間</span> <span class="delivery">{{info.deliveryTime}}分鍾</span> </div> </div> </div> <div class="split"></div> <div class="ratingselect"> <div class="rating-type border-1px"> <span class="block positive" :class="{active: selectType===2}" @click="setSelectType(2)"> 全部<span class="count">{{ratings.length}}</span> </span> <span class="block positive" :class="{active: selectType===0}" @click="setSelectType(0)"> 滿意<span class="count">{{positiveSize}}</span> </span> <span class="block negative" :class="{active: selectType===1}" @click="setSelectType(1)"> 不滿意<span class="count">{{ratings.length-positiveSize}}</span> </span> </div> <div class="switch" :class="{on: onlyShowText}" @click="toggleOnlyShowText"> <span class="iconfont icon-dagou"></span> <span class="text">只看有內容的評價</span> </div> </div> <div class="rating-wrapper"> <ul> <li class="rating-item" v-for="(rating, index) in filterRatings" :key="index"> <div class="avatar"> <img width="28" height="28" :src="rating.avatar"> </div> <div class="content"> <h1 class="name">{{rating.username}}</h1> <div class="star-wrapper"> <Star :score="rating.score" :size="24" /> <span class="delivery">{{rating.deliveryTime}}</span> </div> <p class="text">{{rating.text}}</p> <div class="recommend"> <span class="iconfont" :class="rating.rateType===0 ? 'icon-thumb_up' : 'icon-thumb_down'"></span> <span class="item" v-for="(item, index) in rating.recommend" :key="index">{{item}}</span> </div> <div class="time">{{rating.rateTime | date-format}}</div> </div> </li> </ul> </div> </div> </div> </template> <script> import BScroll from 'better-scroll' import {mapState, mapGetters} from 'vuex' import Star from '../../../components/Star/Star.vue' export default { data () { return { onlyShowText: true, // 是否只顯示有文本的 selectType: 2 , // 選擇的評價類型: 0滿意, 1不滿意, 2全部 } }, mounted () { this.$store.dispatch('getShopRatings', () => { this.$nextTick(() => { new BScroll(this.$refs.ratings, { click: true }) }) }) }, computed: { ...mapState(['info', 'ratings']), ...mapGetters(['positiveSize']), filterRatings () { //條件1: const {onlyShowText, selectType, ratings} = this return this.ratings.filter(rating=>{ const {text, rateType} = rating return (selectType==2 || selectType == rateType)&& (!onlyShowText || text.length>0) }) } }, methods: { setSelectType (selectType) { this.selectType = selectType }, toggleOnlyShowText () { this.onlyShowText = !this.onlyShowText } }, components: { Star }, } </script> <style lang="stylus" rel="stylesheet/stylus"> @import "../../../common/stylus/mixins.styl" .ratings position: absolute top: 195px bottom: 0 left: 0 width: 100% overflow: hidden background: #fff .overview display: flex padding: 18px 0 .overview-left flex: 0 0 137px padding: 6px 0 width: 137px border-right: 1px solid rgba(7, 17, 27, 0.1) text-align: center @media only screen and (max-width: 320px) flex: 0 0 120px width: 120px .score margin-bottom: 6px line-height: 28px font-size: 24px color: rgb(255, 153, 0) .title margin-bottom: 8px line-height: 12px font-size: 12px color: rgb(7, 17, 27) .rank line-height: 10px font-size: 10px color: rgb(147, 153, 159) .overview-right flex: 1 padding: 6px 0 6px 24px @media only screen and (max-width: 320px) padding-left: 6px .score-wrapper margin-bottom: 8px font-size: 0 .title display: inline-block line-height: 18px vertical-align: top font-size: 12px color: rgb(7, 17, 27) .star display: inline-block margin: 0 12px vertical-align: top .score display: inline-block line-height: 18px vertical-align: top font-size: 12px color: rgb(255, 153, 0) .delivery-wrapper font-size: 0 .title line-height: 18px font-size: 12px color: rgb(7, 17, 27) .delivery margin-left: 12px font-size: 12px color: rgb(147, 153, 159) .split width: 100% height: 16px border-top: 1px solid rgba(7, 17, 27, 0.1) border-bottom: 1px solid rgba(7, 17, 27, 0.1) background: #f3f5f7 .ratingselect .rating-type padding: 18px 0 margin: 0 18px border-1px(rgba(7, 17, 27, 0.1)) font-size: 0 .block display: inline-block padding: 8px 12px margin-right: 8px line-height: 16px border-radius: 1px font-size: 12px color: rgb(77, 85, 93) background: rgba(77, 85, 93, 0.2) &.active background: $green color: #fff .count margin-left: 2px font-size: 8px .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-dagou color: $green .icon-check_circle display: inline-block vertical-align: top margin-right: 4px font-size: 24px .text display: inline-block vertical-align: top font-size: 12px .rating-wrapper padding: 0 18px .rating-item display: flex padding: 18px 0 bottom-border-1px(rgba(7, 17, 27, 0.1)) .avatar flex: 0 0 28px width: 28px margin-right: 12px img border-radius: 50% .content position: relative flex: 1 .name margin-bottom: 4px line-height: 12px font-size: 10px color: rgb(7, 17, 27) .star-wrapper margin-bottom: 6px font-size: 0 .star display: inline-block margin-right: 6px vertical-align: top .delivery display: inline-block vertical-align: top line-height: 12px font-size: 10px color: rgb(147, 153, 159) .text margin-bottom: 8px line-height: 18px color: rgb(7, 17, 27) font-size: 12px .recommend line-height: 16px font-size: 0 .icon-thumb_up, .icon-thumb_down, .item display: inline-block margin: 0 8px 4px 0 font-size: 9px .icon-thumb_up color: $yellow .icon-thumb_down color: rgb(147, 153, 159) .item padding: 0 6px border: 1px solid rgba(7, 17, 27, 0.1) border-radius: 1px color: rgb(147, 153, 159) background: #fff .time position: absolute top: 0 right: 0 line-height: 12px font-size: 10px color: rgb(147, 153, 159) </style>
三、總結