文章目录

  • 一、内容介绍
    • 1、内容
    • 2、效果
  • 二、具体实现
    • 1、数据的获取
    • 2、具体布局
    • 3、star组件
    • 4、ratingSelect组件
  • 三、源码

一、内容介绍

1、内容

本篇文章主要介绍的是评价列表的实现。由于评价列表中包含的内容在前面的学习过程中我们都开发过其中的组件,例如星星组件和评价筛选组件。因此在这一部分我们只需要对组件进行复用,然后稍作改动即可。

2、效果

二、具体实现

1、数据的获取

在评价列表展示页实现过程中我们要从服务器端获取评价信息,并且评价列表展示页是可以滚动的,因此使用better-scroll

  created () {axios.get('/api/ratings').then((response) => {response = response.data// console.log(response)if (response.errno === ERR_OK) {this.ratings = response.data// console.log(this.ratings)this.$nextTick(() => {this.scroll = new BScroll(this.$refs.ratings, {click: true})})}})},

2、具体布局

template><div class="ratings" ref="ratings"><div class="ratings-content"><div class="overview"><div class="overview-left"><h1 class="score">{{seller.score}}</h1><div class="title">综合评价</div><div class="rank">高于周边商家{{seller.rankRate}}</div></div><div class="overview-right"><div class="score-wrapper"><span class="title">服务态度</span><Star :size="36" :score="seller.serviceScore" class="star"></Star><span class="score">{{seller.serviceScore}}</span></div><div class="score-wrapper"><span class="title">商品评分</span><Star :size="36" :score="seller.foodScore"></Star><span class="score">{{seller.foodScore}}</span></div><div class="delivery-wrapper"><span class="title">送达时间</span><span class="time">{{seller.deliveryTime}}分钟</span></div></div></div><Split></Split><RatingSelect:select-type="selectType":only-content="onlyContent":ratings="ratings"@type-select="typeSelect"@content-toggle="conToggle"></RatingSelect><div class="ratings-wapper"><ul><liv-for="(rating, index) in ratings" :key="index"class="rating-item"v-show="needShow(rating.rateType,rating.text)"><div class="avatar"><img :src="rating.avatar" width="28" height="28" alt=""></div><div class="content"><h1 class="name">{{rating.username}}</h1><div class="star-wrapper"><Star :score="rating.score" class="star"></Star><span class="time" v-show="rating.deliveryTime">{{rating.deliveryTime}}</span></div><p class="text">{{rating.text}}</p><div class="recommend" v-show="rating.recommend"><span class="iconfont icon-dianzan"></span><span class="item" v-for="(item, index) in rating.recommend" :key="index">{{item}}</span></div><div class="time">{{rating.rateTime | formatDate}}</div></div></li></ul></div></div></div>
</template>

3、star组件

<template><div class="star"><spanv-for="(item,index) in item":key="index":class="item"class="star-item"></span></div>
</template>

定义总的星星的数量和状态

// 定义总的星星的数量和状态const LENGTH = 5const CLS_ON = 'on'const CLS_OFF = 'off'const CLS_HALF = 'half'

通过计算属性根据获取的分数来计算出星星的数量和状态

 computed: {item () {let result = []let score = Math.floor(this.score * 2) / 2let hasDecimal = score % 1 !== 0let integer = Math.floor(score)for (let i = 0; i < integer; i++) {result.push(CLS_ON)}if (hasDecimal) {result.push(CLS_HALF)}while (result.length < LENGTH) {result.push(CLS_OFF)}return result}}

4、ratingSelect组件

      <RatingSelect:select-type="selectType":only-content="onlyContent":ratings="ratings"@type-select="typeSelect"@content-toggle="conToggle"></RatingSelect>

其中的方法和函数跟(4)的实现一样,在这里不详细介绍

 methods: {needShow (type, text) {// 判断是否要显示内容if (this.onlyContent && !text) {return false}// 判断选择的类型if (this.selectType === ALL) {return true} else {return (type === this.selectType)}},typeSelect (type) {this.selectType = type// 由于改变selectType的时候DOM是没有更新的,因此还是需要异步更新this.$nextTick(() => {this.scroll.refresh()})},// 有无内容展示conToggle (onlyContent) {this.onlyContent = onlyContentthis.$nextTick(() => {this.scroll.refresh()})}},filters: {formatDate (time) {let date = new Date(time)return formatDates(date, 'yyyy-MM-dd hh:mm')}}

三、源码

ratings.vue

<template><div class="ratings" ref="ratings"><div class="ratings-content"><div class="overview"><div class="overview-left"><h1 class="score">{{seller.score}}</h1><div class="title">综合评价</div><div class="rank">高于周边商家{{seller.rankRate}}</div></div><div class="overview-right"><div class="score-wrapper"><span class="title">服务态度</span><Star :size="36" :score="seller.serviceScore" class="star"></Star><span class="score">{{seller.serviceScore}}</span></div><div class="score-wrapper"><span class="title">商品评分</span><Star :size="36" :score="seller.foodScore"></Star><span class="score">{{seller.foodScore}}</span></div><div class="delivery-wrapper"><span class="title">送达时间</span><span class="time">{{seller.deliveryTime}}分钟</span></div></div></div><Split></Split><RatingSelect:select-type="selectType":only-content="onlyContent":ratings="ratings"@type-select="typeSelect"@content-toggle="conToggle"></RatingSelect><div class="ratings-wapper"><ul><liv-for="(rating, index) in ratings" :key="index"class="rating-item"v-show="needShow(rating.rateType,rating.text)"><div class="avatar"><img :src="rating.avatar" width="28" height="28" alt=""></div><div class="content"><h1 class="name">{{rating.username}}</h1><div class="star-wrapper"><Star :score="rating.score" class="star"></Star><span class="time" v-show="rating.deliveryTime">{{rating.deliveryTime}}</span></div><p class="text">{{rating.text}}</p><div class="recommend" v-show="rating.recommend"><span class="iconfont icon-dianzan"></span><span class="item" v-for="(item, index) in rating.recommend" :key="index">{{item}}</span></div><div class="time">{{rating.rateTime | formatDate}}</div></div></li></ul></div></div></div>
</template><script>
import BScroll from 'better-scroll'
import Star from '@/components/Star/star'
import Split from '@/components/split/split'
import RatingSelect from '@/components/ratingSelect/ratingSelect'
import axios from 'axios'
import {formatDates} from '@/common/js/date.js'
const ALL = 2
const ERR_OK = 0
export default {props: {seller: {type: Object}},components: {Star,Split,RatingSelect},data () {return {showFlag: false,selectType: ALL,ratings: [],onlyContent: true}},created () {axios.get('/api/ratings').then((response) => {response = response.data// console.log(response)if (response.errno === ERR_OK) {this.ratings = response.data// console.log(this.ratings)this.$nextTick(() => {this.scroll = new BScroll(this.$refs.ratings, {click: true})})}})},methods: {needShow (type, text) {// 判断是否要显示内容if (this.onlyContent && !text) {return false}// 判断选择的类型if (this.selectType === ALL) {return true} else {return (type === this.selectType)}},typeSelect (type) {this.selectType = type// 由于改变selectType的时候DOM是没有更新的,因此还是需要异步更新this.$nextTick(() => {this.scroll.refresh()})},// 有无内容展示conToggle (onlyContent) {this.onlyContent = onlyContentthis.$nextTick(() => {this.scroll.refresh()})}},filters: {formatDate (time) {let date = new Date(time)return formatDates(date, 'yyyy-MM-dd hh:mm')}}
}
</script>
<style>
.ratings{position: absolute;top: 174px;bottom: 0;left: 0;width: 100%;overflow: hidden;
}
.ratings .overview{display: flex;padding: 18px 0;
}
.ratings .overview .overview-left{flex: 0 0 137px;border-right: 1px solid rgba(7, 17, 27, 0.1);text-align: center;padding: 6px 0;
}
.ratings .overview .overview-left .score{line-height: 28px;font-size: 24px;color: rgb(255,153,0);margin-bottom: 6px;
}
.ratings .overview .overview-left .title{font-size: 12px;line-height: 12px;color: rgb(7, 17, 27);margin-bottom: 8px;
}
.ratings .overview .overview-left .rank{font-size: 10px;line-height: 10px;color: rgb(147,153,159);
}
.ratings .overview .overview-right{flex: 1;padding: 6px 0 6px 24px;
}
.ratings .overview .overview-right .score-wrapper{margin-bottom: 8px;font-size: 0;
}
.ratings .overview .overview-right .score-wrapper .title{display: inline-block;vertical-align: top;font-size: 12px;line-height: 18px;color: rgb(7, 17, 27);
}
.ratings .overview .overview-right .score-wrapper .star{display: inline-block;vertical-align: top;margin: 0 12px;
}
.ratings .overview .overview-right .score-wrapper  .score{display: inline-block;line-height: 18px;vertical-align: top;font-size: 12px;color: rgb(255,153,0);
}
.ratings .overview .overview-right .delivery-wrapper{font-size: 0;
}
.ratings .overview .overview-right .delivery-wrapper .title{font-size: 12px;line-height: 18px;color: rgb(7, 17, 27);
}
.ratings .overview .overview-right .delivery-wrapper .time{font-size: 12px;margin-left: 12px;color: rgb(147,153,159);
}
.ratings .ratings-wapper{padding: 0 18px;
}
.ratings .ratings-wapper .rating-item{display: flex;padding: 18px 0;border-bottom: 1px solid rgba(7, 17, 27, 0.1);
}
.ratings .ratings-wapper .rating-item .avatar{flex: 0 0 28px;width: 28px;margin-right: 12px;
}
.ratings .ratings-wapper .rating-item .avatar img{border-radius: 50%;
}
.ratings .ratings-wapper .rating-item .content{position: relative;flex: 1;
}
.ratings .ratings-wapper .rating-item .content .name{margin-bottom: 4px;line-height: 12px;font-size: 10px;color: rgb(7, 17, 27);
}
.ratings .ratings-wapper .rating-item .content .star-wrapper{margin-bottom: 6px;font-size: 0;
}
.ratings .ratings-wapper .rating-item .content .star-wrapper .star{display: inline-block;margin-right: 6px;vertical-align: top;font-size: 10px;
}
.ratings .ratings-wapper .rating-item .content .star-wrapper .time{position: relative;display: inline-block;vertical-align: top;color: rgb(147,153,159);font-size: 12px;margin-top: 5px;line-height: 12px;
}
.ratings .ratings-wapper .rating-item .content .text{line-height: 18px;color: rgb(7, 17, 27);font-size: 12px;margin-bottom: 8px;
}
.ratings .ratings-wapper .rating-item .content .recommend{line-height: 16px;font-size: 0;
}
.ratings .ratings-wapper .rating-item .content .recommend .iconfont,
.ratings .ratings-wapper .rating-item .content .recommend .item{display: inline-block;margin: 0 8px 4px 0;font-size: 9px;
}
.ratings .ratings-wapper .rating-item .content .recommend .iconfont{color: rgb(0,160,220);
}
.ratings .ratings-wapper .rating-item .content .recommend .item{padding: 0 6px;border:  1px solid rgba(7, 17, 27, 0.1);border-radius: 1px;color: rgb(147,153,159);background: #fff;
}
.ratings .ratings-wapper .rating-item .content .time{position: absolute;top: 0;right: 0;line-height: 12px;font-size: 10px;color: rgb(147,153,159);
}
</style>

star.vue

<template><div class="star"><spanv-for="(item,index) in item":key="index":class="item"class="star-item"></span></div>
</template><script>
// 定义总的星星的数量和状态const LENGTH = 5const CLS_ON = 'on'const CLS_OFF = 'off'const CLS_HALF = 'half'
export default {props: {seller: {type: Object},score: {type: Number}},computed: {item () {let result = []let score = Math.floor(this.score * 2) / 2let hasDecimal = score % 1 !== 0let integer = Math.floor(score)for (let i = 0; i < integer; i++) {result.push(CLS_ON)}if (hasDecimal) {result.push(CLS_HALF)}while (result.length < LENGTH) {result.push(CLS_OFF)}return result}}
}
</script><style scoped>
.star{font-size: 0;
}
.star .star-item{display: inline-block;width:15px;height: 15px;margin-right: 6px;background-size: 15px 15px;background-repeat: no-repeat;
}
.star .on{background-image: url('./star36_on@2x.png');
}
.star .half{background-image: url('./star36_half@2x.png');
}
.star .off{background-image: url('./star36_off@2x.png');
}
</style>

Vue.js仿饿了么外卖App--(5)评价列表页实现相关推荐

  1. Vue.js仿饿了么外卖App--(2)头部相关的组件的实现

    本篇文章主要实现的是App.vue组件.头部组件header.蒙层组件detal和Modal以及路由切换router 文章目录 一.App.vue组件 1.重点说明 2.具体实现 (1).整体布局 ( ...

  2. Vue.js仿饿了么外卖App--(4)商品详情页实现

    文章目录 一.内容介绍 1.内容 2.效果 二.具体实现 1.组件传值 2.点击事件 3.图片展示 4.加入购物车 5.分隔条组件 6.评价展示 布局 评价筛选组件 时间展示 三.源码 一.内容介绍 ...

  3. Vue.js仿饿了么外卖App--(6)商家详情页实现

    文章目录 一.内容介绍 1.内容 2.效果 二.具体实现 1.布局 2.滚动实现 三.源码 一.内容介绍 1.内容 商家详情页主要包括商家的具体信息.公告与活动.商家实景和商家信息.其中商家实景这里实 ...

  4. vue开发饿了吗外卖app⑥——goods商品列表页开发和小球飞入动画

    goods组件显示的区域是固定的,也没有滚动条,所以是采用绝对布局的,左右分为menu栏和foods栏,左边固定布局,右边自适应布局,采用flex布局. 写CSS样式的时候,尽量用class,少用ta ...

  5. Vue.js高仿饿了么外卖App学习记录

    (给达达前端加星标,提升前端技能) 开发一款vue.js开发一款app,使用vue.js是一款高效的mvvm框架,它轻量,高效,组件化,数据驱动等功能便于开发.使用vue.js开发移动端app,学会使 ...

  6. vue结合饿了么_Vue.js 高仿饿了么外卖app 全套_IT教程网

    资源名称:Vue.js  高仿饿了么外卖app  全套 资源目录: vue仿饿了么视频全套 全套 资源 │ files.txt │ project.zip │ resource.zip │ ├─第01 ...

  7. 项目:Vue.js高仿饿了吗外卖APP(一)

    Vue.js高仿饿了吗外卖APP核心知识 使用Vue.js作为项目的技术栈!这是目前最火的MVVM框架(之一),轻量.简洁.高效.数据驱动.组件化的优点,被大家称为"简单却不失优雅,小巧而不 ...

  8. Vue.js 高仿饿了么外卖APP

    第1章 课程简介 介绍课程的学习目标和学习内容. 1-1 课程简介 1-2 课程安排 第2章 Vuejs介绍 从前端开发趋势分析开始,引入 MVVM 开发框架和 Vue.js,接着对比流行框架Angu ...

  9. 【慕课网实战课程笔记】Vue.js高仿饿了么外卖App

    写在前面:该课程为慕课网付费课程,笔记内容代码居多.内容简略,仅供自己日后翻阅.如有疑问或者不妥,欢迎提出指正,我看到了会回复,谢谢! 第1章:课程简介 第2章:Vuejs介绍 Ctrl+Alt+l ...

最新文章

  1. docker查看容器创建命令
  2. 4、SpringBoot 配置和使用定时任务
  3. tableau certificate
  4. 阿里云马涛:因云进化的基础软件
  5. 1. InteliJ IDEA 下 的SpringBoot
  6. 【100题】三十五 求一个矩阵中最大的二维矩阵(元素和最大)
  7. CEPH RGW集群和bucket的zone group 不一致导致的404异常解决 及 使用radosgw-admin metadata 命令设置bucket metadata 的方法
  8. 三、synchronized同步锁
  9. 【性能测试】性能数据采集工具nmon安装使用及报告参数含义详解
  10. [No0000105]java sdk 开发环境变量powershell 自动配置脚本
  11. PS-elevenday-铅笔工具(颜色替换)
  12. centos host在哪 local_centos怎么查看hostid
  13. 尺度空间-多尺度特征空间
  14. 启动tomcat报错:Destroying ProtocolHandler [ajp-nio-8009]
  15. Linux基础知识学习笔记
  16. 2023年全国最新交安安全员精选真题及答案4
  17. python 技巧总结_python技巧汇总
  18. HDU 3265 - Posters
  19. 一文教你如何使用miniconda
  20. 4084: [Sdoi2015]双旋转字符串

热门文章

  1. easyPoi二级表头,自定义合并行列方法
  2. 耳朵经济频现风口,荔枝能把握住吗
  3. mysql binlog跟踪_在MySQL中使用init-connect与binlog来实现用户操作追踪记录
  4. airbnb数据_Airbnb的数据驱动故事
  5. Office设置不同章节的页眉页脚及下划线的清除与添加
  6. 电子商务中:B2C、B2B、C2B、C2C、O2O、P2P
  7. R绘制时间序列图形(time series)
  8. Java注释炫酷写法
  9. 数学建模常用算法汇总及python,MATLAB实现(二)—— 整数规划
  10. Python3——替换空格