需求:一组数据中,多条数据都需要 “水波纹进度条” 的情况,封装成组件即可
一、创建组件 WaterRipple.vue
<template>
<div class="water_progress" :style="'top:'+size.top+';left:'+size.left+';'">
<div id="num">{{numTxt}}</div>
<div class="water">
<div class="water_bg"></div>
</div>
<div class="water-mask" :id="id"></div>
</div>
</template>
<script>
export default {
props: {
size: {
type: Object,
default: () => {}
},
id: {
type: String,
default: ''
},
proNum: {
type: Number,
default: 0
},
isTodo: {
type: Boolean,
default: false
}
},
data () {
return {
numTxt: 0,
timerRef: null,
progress: 50
}
},
created () {
setTimeout(() => {
this.loadBtn()
}, 2000)
},
methods: {
loadBtn () {
this.progress = this.proNum
this.numTxt = this.progress >= 100 ? 100 : this.progress.toFixed(2) + '%'
let waterEle = document.getElementById(this.id)
waterEle.style.top = (100 - this.progress) + '%'
}
}
}
</script>
<style lang="scss" scoped>
@keyframes spin {
50% {
transform: translate(-50%, -101%) rotate(500deg);
}
100% {
transform: translate(-50%, -101%) rotate(1000deg);
}
}
.water_progress {
width: 100px;
height: 100px;
border-radius: 50%;
background: #ffffff;
overflow: hidden;
position: relative;
}
.water_active{
background: url('../../assets/home/more_bg1.png') !important;
background-size: 100% 100% !important;
}
.water_bg_active{
background: url('../../assets/home/kong_bg1.png') !important;
background-size: 100% 100% !important;
}
.water {
position: relative;
width: 100%;
height: 100%;
background: url('../../assets/home/more_bg.png');
background-size: 100% 100%;
border-radius: 50%;
.water_bg{
background: url('../../assets/home/kong_bg.png');
background-size: 100% 100%;
position: absolute;
z-index: 100;
width: 100%;
height: 100%;
}
}
.water-mask {
position: absolute;
width: 200%;
height: 200%;
top: 0;
left: 50%;
border-radius: 40%;
transform: translate(-50%, -101%) rotate(0);
animation: spin 30s linear;
z-index: 20;
background: #05204c;
}
#num {
position: absolute;
width: 100%;
height: 100%;
color: #fff;
font-size: 16px;
line-height: 100px;
font-weight: bold;
text-align: center;
z-index: 100;
}
</style>
二、页面调用
<template>
<div>
<div v-for="(task, taIndex) of taskDetailList" :key="taIndex">
// 引入
<WaterRipple :size="{top:'-190px',left:'106px'}" :proNum="task.finishNum" :isTodo="task.isTodo" :id="taIndex"></WaterRipple>
</div>
</div>
</template>
<script>
import WaterRipple from '@/components/WaterRipple/index'
export default {
components: { WaterRipple },
data () {
return {
taskDetailList: [
{id: 1, typeid: 1, finishNum: 10, name: '1三角函数原理', status: '未完成', isTodo: true}]
}
}
}
</script>
示例:
<template>
<div class="learn_page">
<div class="learn_list">
<div class="learn_scroll">
<div class="learn_item" v-for="(task, taIndex) of taskDetailList" :key="taIndex">
<div v-if="task.typeid==checkIndex" class="l_item">
<div class="item_point" :class="taIndex!==0?'':'hidden'">
<div class="po_img"></div>
</div>
<div class="item_cont">
<img class="item_img" src="@/assets/home/item_points.png" alt="">
// 引入
<WaterRipple :size="{top:'-190px',left:'106px'}" :proNum="task.finishNum" :isTodo="task.isTodo" :id="taIndex"></WaterRipple>
<div class="item_cont_txt">
<div class="txt_name">{{task.name}}</div>
<div class="txt_btn" v-if="task.status!=='已完成'||!task.isTodo">已掌握,跳过</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import WaterRipple from '@/components/WaterRipple/index'
export default {
components: { WaterRipple },
data () {
return {
checkIndex: 1,
taskDetailList: [
{id: 1, typeid: 1, finishNum: 10, name: '1三角函数原理', status: '未完成', isTodo: true},
{id: 2, typeid: 1, finishNum: 50, name: '1三角函数原理', status: '已完成', isTodo: false},
{id: 3, typeid: 1, finishNum: 100, name: '1三角函数原理', status: '已完成', isTodo: true},
{id: 4, typeid: 1, finishNum: 80, name: '1三角函数原理', status: '未完成', isTodo: false},
{id: 5, typeid: 1, finishNum: 60, name: '1三角函数原理', status: '未完成', isTodo: true}
]
}
}
}
</script>
<style lang="scss" scoped>
.learn_page {
background: url('../../assets/home/tasks_bg.png');
background-size: 100% 100%;
height: 100vh;
width: 100%;
color: #fff;
// 内容
.learn_list{
background:url('../../assets/home/task_lis_bg.png') no-repeat;
background-size: 100% 100%;
margin: 20px 90px;
height: 905px;
padding: 40px 85px 0px 55px;
user-select: none;
.learn_scroll::-webkit-scrollbar{
width: 0;
}
.learn_scroll{
width: 100%;
height: 830px;
overflow-x: scroll;
display: flex;
-webkit-overflow-scrolling: touch;
}
.learn_item:first-child{
margin-left: 40px;
}
// 偶数
.learn_item:nth-child(even){
margin-top: 470px;
.po_img{
position: absolute;
top: -100px;
left: -45px;
width: 65px;
height: 67px;
background: url('../../assets/home/task_left.png');
background-size: 100% 100%;
}
.po_left{
background: url('../../assets/home/task_left_active.gif') !important;
background-size: 100% 100% !important;
}
.l_item{
margin-left: -45px;
}
}
// 奇数
.learn_item:nth-child(odd){
.po_img{
position: absolute;
top: 370px;
left: 0px;
width: 65px;
height: 67px;
background: url('../../assets/home/task_right.png');
background-size: 100% 100%;
}
.po_right{
background: url('../../assets/home/task_right_active.gif') !important;
background-size: 100% 100% !important;
}
.l_item{
margin-left: -45px;
}
}
.learn_item {
position: relative;
width: 18.6%;
.l_item{
display: flex;
align-items: center;
.item_cont{
align-items: center;
position: relative;
img{
width: 393px;
height: 251px;
margin-top: 15px;
}
.item_cont_txt{
margin-top: -110px;
.txt_name{
color: #0378D2;
font-size: 28px;
text-shadow: 0px 4px 2px rgba(0, 0, 0, 0.58);
}
.txt_btn{
margin: 0 auto;
width: 237px;
height: 42px;
line-height: 42px;
font-size: 22px;
margin-top: 10px;
background: url('../../assets/home/task_btns.png');
background-size: 100% 100%;
}
}
}
}
}
}
}
.hidden{
display: none;
}
</style>
希望我的愚见能够帮助你哦~,若有不足之处,还望指出,你们有更好的解决方法,欢迎大家在评论区下方留言支持,大家一起相互学习参考呀~