简介
利用js原生写的一个移动端进度条
效果展示
代码实现
<template>
<div class="steps flex flex-wrap">
<div class="step-item flex flex-col flex-items flex-jc" v-for="(item, index) in arr" :key="index">
<!-- 可自由发挥的地方 -->
<div class="flex flex-items flex-jc">{{item.rank}}</div>
<!-- 可自由发挥的地方结束 -->
<div class="step-word">{{item.num}}</div>
<div class="step-line"></div>
<div class="heart-icon flex flex-item flex-jc">
<img width="15" :src="!item.done ? 'https://img-blog.csdnimg.cn/52f0ece61c264672bc87a8ac85e48a3f.png' : 'https://img-blog.csdnimg.cn/47a05243bb174f6b9415ed3a64c08a02.png'" alt="">
</div>
<div class="step-now flex flex-items flex-jc" style="display: none;">{{now}}</div>
</div>
</div>
</template>
<script>
export default {
name: 'Step',
props: {
arr: {
type: Array,
required: true
},
now: {
type: Number
}
},
data () {
return {}
},
created () {},
mounted () {
var items = document.querySelectorAll('.step-line')
var signs = document.querySelectorAll('.step-now')
var index = 0
if (this.now < this.arr[0].num) {
items[0].style.width = this.now / this.arr[0].num * 50 + '%'
index = 0
} else if (this.now >= this.arr[this.arr.length - 1].num) {
for (var i = 0; i < this.arr.length - 1; i++) {
items[i].style.width = '100%'
this.$set(this.arr[i], 'done', true)
}
items[this.arr.length - 1].style.width = '50%'
this.$set(this.arr[this.arr.length - 1], 'done', true)
} else {
for (var j = 0; j < this.arr.length - 1; j++) {
if (this.now > this.arr[j].num) {
if (this.now - this.arr[j].num > (this.arr[j + 1].num - this.arr[j].num) / 2) {
items[j].style.width = '100%'
this.$set(this.arr[j], 'done', true)
items[j + 1].style.width = (this.now - this.arr[j].num) / (this.arr[j + 1].num - this.arr[j].num) * 100 - 50 + '%'
if (items[j + 1].style.width === '50%') {
this.$set(this.arr[j + 1], 'done', true)
}
index = j + 1
continue
}
items[j].style.width = (this.now - this.arr[j].num) / (this.arr[j + 1].num - this.arr[j].num) * 100 + 50 + '%'
index = j
this.$set(this.arr[j], 'done', true)
break
}
}
}
if (this.now < this.arr[this.arr.length - 1].num) {
signs[index].style.display = 'block'
signs[index].style.left = items[index].style.width
signs[index].style.transform = 'translateX(-50%)'
}
},
methods: {}
}
</script>
<style lang="less" scoped>
.flex {
display: flex;
}
.flex-items {
align-items: center;
}
.flex-jc {
justify-content: center;
}
.flex-bet {
justify-content: space-between;
}
.flex-aro {
justify-content: space-around;
}
.flex-wrap {
flex-wrap: wrap;
}
.flex-col {
flex-direction: column;
}
.steps {
width: 100%;
.step-item {
position: relative;
width: 33%;
margin: 10px 0;
padding-bottom: 10px;
.step-line {
position: absolute;
width: 0;
height: 1px;
background: #f00;
left: 0;
bottom: 0;
z-index: 5;
}
.step-now {
font-size: 8px;
color: #fff;
position: absolute;
padding: 1px 4px;
bottom: 0;
height: 26px;
line-height: 26px;
z-index: 15;
background: url(http://h5.dongjinyu.com/icon/20210825094601_6125a0d92163e.png);
background-size: 100% 100%;
}
.heart-icon {
position: absolute;
width: 20px;
bottom: -8px;
background: #fff;
z-index: 10;
}
}
.step-item:not(:last-child):before {
width: 100%;
height: 1px;
content: '';
position: absolute;
left: 0;
bottom: 0;
background: #E9E9E9;
}
.step-item:last-child:before {
width: 50%;
height: 1px;
content: '';
position: absolute;
left: 0;
bottom: 0;
background: #E9E9E9;
}
}
</style>
使用方式
1、引用使用
<Step :arr="list" :now="now"></Step>
2、传入参数样例
list: [{
num: 100,
rank: '幼儿园'
}, {
num: 200,
rank: '小学'
}, {
num: 400,
rank: '初中'
}, {
num: 800,
rank: '高中'
}, {
num: 1600,
rank: '大学'
}, {
num: 3200,
rank: '硕士'
}, {
num: 6400,
rank: '博士'
}, {
num: 12800,
rank: '博士后'
}, {
num: 25600,
rank: '博士导师'
}, {
num: 51200,
rank: '国宝'
}],
now: 730
3、注意事项
(1)每一项的rank内容部分可以自由发挥
(2)如果传入的list数组中的数值键名不是num,需要在vue文件中的js中将所有num改为list数组中数值的键名,dom项的属性也自行修改