vue进度条各产品不合格数量占比效果

vue yekong

vue 数据可视化大屏 实现进度条效果,效果通过颜色实现渐变色进度条。

vue进度条各产品不合格数量占比效果

演示地址

使用组件

<template>
  <div class="cardBody">
    <div class="cardBodyList">
      <list></list>
    </div>
  </div>
</template>

<script>
import WOW from "wow.js";
import numcard from "@/components/numcard/numcard.vue";
import gsap from 'gsap'
import list from './list.vue'

export default {
  name: "title",
  data() {
    return {}
  },
  components: {numcard, list},
  watch: {},
  mounted() {
    var that = this;
    var wow = new WOW({
      boxClass: "wow",
      animateClass: "animated",
      offset: 0,
      mobile: true,
      live: true,
      scrollContainer: null,
      resetAnimation: true,
    });
    wow.init();
    gsap.to(this.$refs.icon, {
      duration: 1, y: 3, repeat: -1, delay: 2, yoyo: true, onComplete: () => {
        console.log('动画完成')
      }
    })
  },
}
</script>

<style lang="scss" scoped>
.cardBody {
  position: relative;
  width: calc(100% - 70px);
  margin: 0 auto;
  height: 100%;
  display: flex;
  justify-content: flex-start;
  align-items: flex-start;
  flex-wrap: nowrap;
  flex-direction: column;
  align-content: flex-start;

  .cardBodyList {
    position: relative;
    width: 100%;
    height: calc(100% - 60px);
  }

  .cardBodyItem {
    width: calc(100% - 0px);
    height: 100%;
    height: 93px;
    position: relative;
    background: url("./assets/cardbg.png") no-repeat;
    background-size: 100% 100%;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    flex-wrap: nowrap;
    flex-direction: row;
    align-content: flex-start;

    .infoBody {
      display: flex;
      justify-content: space-between;
      align-items: center;
      flex-wrap: nowrap;
      width: calc(100% - 110px);
      flex-direction: row;
      align-content: flex-start;

      .infoBottom {
        display: flex;
        width: 100%;
        position: relative;
        justify-content: space-between;
        align-items: center;
        flex-wrap: nowrap;
        flex-direction: row;
        align-content: flex-start;
      }
    }

    .title {
      font-size: 16px;
      font-family: MicrosoftYaHei;
      font-weight: 400;
      color: #FFFFFF;
      display: flex;
      justify-content: flex-start;
      align-items: flex-start;
      flex-wrap: nowrap;
      flex-direction: row;
      align-content: flex-start;
      padding-top: 10px;

      img {
        width: 10px;
        height: 18px;
        margin-right: 7px;
      }
    }

    .info {
      margin-left: 0px;
      width: 100%;
    }

    .num {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-wrap: nowrap;
      flex-direction: row;
      align-content: flex-start;

      span {
        font-size: 12px;
        font-family: MicrosoftYaHei;
        font-weight: 400;
        color: #7989A6;
        margin-left: 5px;
        margin-top: 5px;
      }
    }

    .tb {
      display: flex;
      justify-content: flex-end;
      align-items: center;
      flex-wrap: nowrap;
      flex-direction: row;
      align-content: flex-start;

      img {
        width: 10px;
        height: 13px;
        margin-left: 8px;
      }

      .tbTitle {
        font-size: 12px;
        font-family: MicrosoftYaHei;
        font-weight: 400;
        color: #FFFFFF;
        margin-right: 7px;
      }

      .tbDescMinus {
        display: flex;
        justify-content: flex-start;
        align-items: center;
        flex-wrap: nowrap;
        flex-direction: row;
        align-content: flex-start;
        font-size: 16px;
        font-family: DIN-Bold;
        font-weight: bold;
        color: #30E17F;
      }

      .tbDesc {
        display: flex;
        justify-content: flex-start;
        align-items: center;
        flex-wrap: nowrap;
        flex-direction: row;
        align-content: flex-start;
        font-size: 16px;
        font-family: DIN-Bold;
        font-weight: bold;
        color: rgba(237, 37, 80, 1);
      }
    }

    :deep(.num) {
      .real-time-num {
        font-size: 26px;
        font-family: DIN;
        font-weight: normal;
        color: #FFFFFF;
        width: auto;
      }

      .real-time-num-item {
        text-shadow: 0 0 8px rgba(66, 163, 236, 1.00);
      }

    }

    .icon {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-wrap: nowrap;
      flex-direction: row;
      align-content: flex-start;
      background: url("./assets/cardiconbg.png") no-repeat;
      width: 58px;
      height: 68px;
      margin-left: 20px;
      background-size: 100% 100%;
      margin-right: 15px;

      img {
        height: 30px;
      }
    }
  }
}
</style>

组件代码

<template>
  <div class="list">
    <div class="listBody scrollBar">
      <progressBar :index="index" :total="total" :item="item" v-for="(item,index) in list" :key="index"></progressBar>
    </div>
  </div>
</template>

<script>
import WOW from "wow.js";
import numcard from "@/components/numcard/numcard.vue";
import gsap from 'gsap'
import progressBar from './progressBar.vue'

export default {
  name: "title",
  data() {
    return {
      list: [{
        title: '糕点饼干',
        num: 80,
        color: 'rgba(130, 202, 253, 1)',
        color2: 'rgba(22, 153, 255, 1)',
      }, {
        title: '禽肉及杂碎',
        num: 70,
        color: 'rgba(107, 192, 172, 1)',
        color2: 'rgba(104, 230, 167, 1)',
      }, {
        title: '其他饮料',
        num: 60,
        color: 'rgba(108, 207, 246, 1)',
        color2: 'rgba(0, 198, 195, 1)',
      }, {
        title: '可可、巧克力、代可可脂巧克力及其制品',
        num: 50,
        color: 'rgba(166, 98, 192, 1)',
        color2: 'rgba(143, 105, 241, 1)',
      }, {
        title: '发酵酒',
        num: 50,
        color: 'rgba(253, 192, 74, 1)',
        color2: 'rgba(244, 130, 50, 1)',
      }]
    }
  },
  computed: {
    total() {
      var total = 0
      this.list.forEach((type) => {
        total += type.num
      });
      return total
    }
  },
  components: {numcard, progressBar},
  watch: {},
  mounted() {
    var that = this;
    var wow = new WOW({
      boxClass: "wow",
      animateClass: "animated",
      offset: 0,
      mobile: true,
      live: true,
      scrollContainer: null,
      resetAnimation: true,
    });
    wow.init();
    gsap.to(this.$refs.icon, {
      duration: 1, y: 3, repeat: -1, delay: 2, yoyo: true, onComplete: () => {
        console.log('动画完成')
      }
    })
  },
}
</script>

<style lang="scss" scoped>
.list {
  position: relative;
  width: 100%;
  height: 100%;

  .title {
    font-size: 14px;
    font-family: MicrosoftYaHei;
    font-weight: 400;
    color: #FFFFFF;
    height: 40px;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    flex-wrap: nowrap;
    flex-direction: row;
    align-content: flex-start;
  }
}

.listBody {
  position: relative;
  width: 100%;
  height: calc(100% - 46px);
  overflow-y: scroll;
}

.progressBarInner {
  height: 10px;
  background: linear-gradient(180deg, #04CEF7 0%, #1263FF 100%);
  opacity: 1;
  width: 0%;
  max-width: calc(100% - 60px);
}

.progressBarl {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: nowrap;
  flex-direction: row;
  align-content: flex-start;
}

.line {
  height: 12px;
  width: 2px;
  background: #04CEF7;
  opacity: 1;
  margin-left: 2px;
}
</style>


子组件进度

/**
* @Author: 858834013@qq.com
* @Name: progressBar
* @Date: 2023年04月27日
* @Desc:

*/
<template>
  <div class="progressBarBody">
    <div class="progressBarBodyl">
      <div class="progressBarBodylTitle">
        <img src="./assets/icon_1.png" alt=""> <span>top.{{ index + 1 }}</span><span>{{ item.title }}</span>
      </div>
      <div class="progressBarBottom">
        <div class="progressBar">
          <div class="progressBarInner"
               :class="'progressBarInner'+(index+1)"
               ref="progressBarInner"></div>
        </div>
      </div>
    </div>
    <div class="progressBarBodyr">
      <div class="zbtitle"><span v-if="index==0">批次数</span></div>
      <div class="width">
        195
      </div>
    </div>
  </div>
</template>

<script>
import gsap from 'gsap'

export default {
  name: "progressBar",
  components: {},
  props: {
    index: {
      type: Number,
      default() {
        return 0
      }
    },
    item: {
      type: Object,
      default() {
        return {};
      }
    },
    total: {
      type: Number,
      default() {
        return 0
      }
    },
  },
  computed: {
    width: function () {
      return ((this.item.num / this.total) * 100).toFixed(0)
    }
  },
  data() {
    return {}
  },
  watch: {},
  mounted() {
    var that = this;
    gsap.to(this.$refs.progressBarInner, {
      duration: 1, width: this.width + '%', delay: 3, onComplete: () => {
        console.log('动画完成')
      }
    })
  },
  methods: {}
}
</script>

<style lang="scss" scoped>
.progressBarBody {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  flex-wrap: nowrap;
  width: 100%;
  flex-direction: row;
  align-content: flex-start;
  margin-top: 10px;

  .progressBarBodyl {
    width: calc(100% - 50px);
    display: flex;
    justify-content: flex-start;
    align-items: flex-start;
    flex-wrap: nowrap;
    flex-direction: column;
    align-content: flex-start;

    .progressBarBodylTitle {
      display: flex;
      justify-content: flex-start;
      align-items: center;
      flex-wrap: nowrap;
      flex-direction: row;
      align-content: flex-start;
      font-size: 14px;
      font-family: MicrosoftYaHei;
      font-weight: 400;
      color: #9DB9E9;

      img {
        margin-right: 14px;
      }

      span {
        font-size: 14px;
        font-family: MicrosoftYaHei;
        font-weight: 400;
        color: #CAD7F5;
        margin-right: 15px;
      }
    }

    .progressBarBottom {
      display: flex;
      width: calc(100% - 0px);
      margin-left: 38px;
      justify-content: flex-start;
      align-items: center;
      flex-wrap: nowrap;
      flex-direction: row;
      height: 30px;
      align-content: flex-start;

      .Num {
        font-size: 22px;
        font-family: DIN;
        font-weight: normal;
        color: #FFFFFF;
        margin-left: 16px;
        text-shadow: 0 0 10px rgba(14, 156, 255, 1.00);
      }

    }
  }

  .progressBarBodyr {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100px;
    flex-wrap: nowrap;
    flex-direction: column;
    align-content: flex-start;

    .zbtitle {
      height: 15px;
      display: flex;
      justify-content: center;
      align-items: center;
      flex-wrap: nowrap;
      flex-direction: row;
      font-size: 14px;
      font-family: MicrosoftYaHei;
      font-weight: 400;
      color: #9DB9E9;
      align-content: flex-start;
    }

    .width {
      width: 62px;
      height: 22px;
      background: linear-gradient(0deg, rgba(#0570E9, 0.2) 0%, rgba(#0ECFF8, 0.2) 100%);
      display: flex;
      justify-content: center;
      align-items: center;
      flex-wrap: nowrap;
      flex-direction: row;
      align-content: flex-start;
      font-size: 14px;
      font-family: MicrosoftYaHei;
      font-weight: 400;
      color: #FFFFFF;
      margin-top: 10px;
    }
  }
}

.progressBar {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  flex-wrap: nowrap;
  flex-direction: row;
  background: url("./assets/jindux0.png") no-repeat;
  background-size: 410px 100%;
  height: 9px;
  width: calc(100% - 0px);
  position: relative;

  .progressBarInner {
    position: relative;
    left: 0;
    height: 9px;
    width: 0%;
    background: url("./assets/jindux5.png") no-repeat;
    background-size: 410px 100%;
  }

  .progressBarInner1 {
    background: url("./assets/jindux1.png") no-repeat;
    background-size: 410px 100%;
  }

  .progressBarInner2 {
    background: url("./assets/jindux2.png") no-repeat;
    background-size: 410px 100%;
  }

  .progressBarInner3 {
    background: url("./assets/jindux3.png") no-repeat;
    background-size: 410px 100%;
  }

  .progressBarInner4 {
    background: url("./assets/jindux4.png") no-repeat;
    background-size: 410px 100%;
  }

  .Num {
    font-size: 16px;
    font-family: DIN-Bold;
    font-weight: bold;
    color: #0BFFF1;
    margin-left: 10px;
  }
}
</style>


更多进度条效果实例

vue 数据可视化大屏进度条效果实例

项目应用

vue3 可视化数据大屏 - 进口食品安全智慧监管决策大屏

喜欢