vue 数据可视化大屏 项目开发中经常会遇到各种各样的进度条效果,想来将来可能会遇到类似的效果就将对应的效果实例给记录下来。
如果您需要设计属于自己的 可视化数据大屏 可以联系我们微信:17331886870
组件代码
<template>
<div class="list">
<div class="listItem wow fadeInLeft" :data-wow-delay="0+0.3*index+'s'"
v-for="(item,index) in list"
:key="index">
<progressBar :total="total" :item="item"></progressBar>
</div>
</div>
</template>
<script>
import progressBar from "./progressBar.vue";
import WOW from "wow.js";
export default {
data() {
return {
list: [
{
title: '51岁及以上',
num: 2000,
color: 'rgba(254, 217, 82, 1)',
color2: 'rgba(253, 168, 62, 1)',
id: 'teacherTypeFullTime'
},
{
title: '31岁到50岁',
num: 210,
color: 'rgba(6, 180, 143, 1)',
color2: 'rgba(14, 224, 159, 1)',
id: 'teacherTypeOffCampus'
},
{
title: '30岁以下',
num: 2210,
color: 'rgba(242, 89, 22, 1)',
color2: 'rgba(224, 123, 14, 1)',
id: 'teacherTypeGraduateDegree'
}]
}
},
props: {
title: {
type: String,
default() {
return '';
}
}
},
components: {progressBar},
computed: {
total: function () {
var total = 0
this.list.forEach((type) => {
total = total + type.num
});
return total
}
},
mounted() {
var that = this;
var wow = new WOW({
boxClass: "wow", // animated element css class (default is wow)
animateClass: "animated", // animation css class (default is animated)
offset: 0, // distance to the element when triggering the animation (default is 0)
mobile: true, // trigger animations on mobile devices (default is true)
live: true, // act on asynchronously loaded content (default is true)
callback: function (box) {
// the callback is fired every time an animation is started
// the argument that is passed in is the DOM node being animated
},
scrollContainer: null, // optional scroll container selector, otherwise use window,
resetAnimation: true, // reset animation on end (default is true)
});
wow.init();
},
methods: {},
filters: {},
watch: {}
}
</script>
<style lang="scss" scoped>
.list {
width: calc(100% - 0px);
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: column;
align-content: flex-start;
height: 100%;
.listItem {
font-size: 14px;
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: nowrap;
flex-direction: column;
align-content: flex-start;
height: 30%;
width: 100%;
}
}
</style>
进度条代码
/**
* @Author: 858834013@qq.com
* @Name: progressBar
* @Date: 2023年05月13日20:14:16
* @Desc: 进度条效果
*/
<template>
<div class="progressBarBody">
<div class="progressBarBodyTitle">
<div class="progressBarBodyTitlel">{{ item.title }}</div>
<div class="progressBarBodyTitler"><span>{{ item.num }}</span>人</div>
</div>
<div class="progressBar">
<div class="progressBarInner"
:style="{background: 'linear-gradient(180deg, '+item.color+' 0%, '+item.color2+' 100%)'}"
ref="progressBarInner"></div>
<div class="line"></div>
</div>
</div>
</template>
<script>
import gsap from "gsap";
export default {
name: "progressBarBody",
props: {
item: {
type: Object,
default() {
return {}
}
},
total: {
type: Number,
default() {
return 0
}
},
},
data() {
return {}
},
computed: {
width: function () {
return (this.item.num / this.total).toFixed(2) * 100
}
},
mounted() {
setTimeout(() => {
gsap.to(this.$refs.progressBarInner, {
duration: 1.5, width: this.width + '%', onComplete: () => {
console.log('动画完成')
}
})
}, 1000)
},
methods: {}
}
</script>
<style lang="scss" scoped>
.progressBarBody {
display: flex;
justify-content: flex-start;
align-items: flex-start;
flex-wrap: nowrap;
flex-direction: column;
align-content: flex-start;
width: calc(100% - 0px);
.Num {
font-size: 14px;
font-family: DIN-Bold, DIN;
font-weight: bold;
color: #FFFFFF;
position: absolute;
width: 100%;
display: flex;
justify-content: flex-end;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
span {
margin-right: 6px;
}
}
.progressBarBodyTitle {
font-size: 13px;
font-family: PingFang SC-Bold, PingFang SC;
font-weight: bold;
color: #D7E7FF;
height: 40px;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
.progressBarBodyTitler {
display: flex;
justify-content: flex-end;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
span {
font-size: 18px;
font-family: DIN-Bold;
font-weight: 500;
color: #FFFFFF;
margin-right: 10px;
text-shadow:0 0 12px #1263FF;
}
}
}
.progressBar {
width: 100%;
height: 6px;
background: linear-gradient(180deg, rgba(#04CEF7, 0.2) 0%, rgba(#1263FF, 0.2) 100%);
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
position: relative;
}
}
.progressBarInner {
height: 6px;
background: linear-gradient(180deg, #04CEF7 0%, #1263FF 100%);
opacity: 1;
width: 0%;
max-width: calc(100% - 0px);
}
.progressBarl {
display: flex;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
}
.line {
background: url("./assets/jinduImg.png");
width: 26px;
height: 26px;
opacity: 1;
margin-left: -13px;
}
.progressBarBodyTitle {
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
}
</style>
更多进度条效果实例
完整运行实例
代码运行环境 vue3 vite js nodejs14