【Vue】自己编写排名组件

发布时间 2023-10-08 09:10:10作者: emdzz

一、需求分析

这里我是用Echarts的柱状图,倒置下y轴x轴就实现了,然后产品说跟UI不一致

我一看UI这种又给我整不会了,然后想拿Echarts改改参数搞定,同事和群友都是说自己做,不要用Echarts改

 

二、实现思路

同事劝我用ElementUI的进度条组件来实现,进度条见:

https://element.eleme.io/#/zh-CN/component/progress

想了下这个思路还是可行的,上面的标题自定义起来还算方便

然后花了点时间抓的进度条的样式

 

组件解析后是这样的:

<div class="el-progress-bar">
  <div class="el-progress-bar__outer" style="height: 20px; background-color: rgb(235, 238, 245);">
    <div class="el-progress-bar__inner" style="width: 44%; background-color: rgb(27, 189, 236);"></div>
  </div>
</div>

一个bar嵌套 一个outer和inner

outer就是百分百的长度,outer是相对定位

inner用来展示占比的长度,inner是绝对定位

所以在做UI效果的时候花了很多时间琢磨这个东西,outer来设置底部边框线

然后想通过设置外边距和内边距来拉开inner的间隙,在知道是绝对定位后,改用top定位属性才拉开

 

这里我直接上效果图:

 

自己封装的RankCharts组件:

<template>
  <div>
    <div v-for="(item, idx) in rankList" :key="idx" style="margin-bottom: 15px;">
      <div class="rank-header"><span>No.{{ idx + 1 }} {{ item[labelField] }}</span> <span style="float: right">{{ item[countField] }}</span></div>
      <el-progress :percentage="item.percent" :stroke-width="15" :color="customColor" text-inside :show-text="false" />
    </div>
  </div>
</template>

<script>
export default {
  name: 'RankCharts',
  props: {
    rankList: {
      type: Array,
      required: true,
      default: () => []
    },
    labelField: {
      type: String,
      required: true,
      default: ''
    },
    countField: {
      type: String,
      required: true,
      default: ''
    }
  },
  data() {
    return {
      customColor: '#1BBDEC',
      completeVal: 0
    }
  }
}
</script>

<style scoped>
/* 进度条的圆角移除 */
/deep/ .el-progress-bar__outer,
/deep/ .el-progress-bar__inner {
  border-radius: 0;
}
/* 移除进度条的底色,设置底部百分百线条 */
/deep/ .el-progress-bar__outer {
  background-color: unset !important;
  border-bottom: 1px #1BBDEC solid;
}
/* 拉开进度条底线和占比的间距 */
/deep/ .el-progress-bar__inner {
  top: -2px;
}
/* 进度条上面的排名信息展示 */
.rank-header {
  color: #1BBDEC;
  margin-bottom: 5px;
  font-size: 18px;
}
</style>

  

组件使用:

<rank-charts :rank-list="carSourceList" count-field="val" label-field="label" style="padding: 10px;" />

接口数据处理:

因为进度条组件的进度是自己计算的,排名按最多的那个为100%来算

设置一个percent属性即可实现

 async initializeCarSourceData(regionCode, [startTime, endTime]) {
   const { data: carSourceData } = await getStatisticDataAnalysisOfCarSource(regionCode, { startTime, endTime })
   this.carSourceList = carSourceData['countList'].map((val, idx, arr) => ({
     val,
     label: carSourceData['nameList'][idx],
     percent: (val / arr[0]).toFixed(2) * 100
   }))
 },