持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情
概述
大屏开发中有很多类型进度条功能,今天我们就用 Vue3实现一个进度条功能, 我们先来看看实现后的效果:
项目初始化
首先我们新建一个项目,执行如下命令
pnpm create vite vue-circleprogress
选择 vue ,回车,等待项目安装完成, cd 进入项目根目录下,接着安装项目需要的依赖包
pnpm install
安装完成后,我们启动项目
pnpm run dev
控制台输出如下内容
vite v2.9.10 dev server running at:
> Local: http://localhost:3000/
> Network: use `--host` to expose
ready in 353ms.
说明项目正常启动了,下面我们接着开发
进度条
我们先删除项目中多余的内容,新建组件文件 src/components/circleProgress.vue, 添加如下内容
<template>
<div class="progress">
</div>
</template>
<script setup>
import { ref, toRefs, watch, onMounted } from 'vue'
</script>
<style lang="css" scoped>
.progress {
display: inline-block;
position: relative;
height: 100px;
}
</style>
实现进度条的功能可以使用 canvas 和 svg 等方案,考虑性能方面可以用 svg 来实现,我们这里了用的就是这种方式。
首先我们需要一个 svg
<svg viewBox="0 0 96 96" ref="circleRef" style="width: 96px; height: 96px;">
<circle r="40" cx="48" cy="48" fill="none" stroke-miterlimit="20" stroke-width="10" style="stroke-dasharray: 275, 279.602;stroke:#eee;">
</circle>
<circle r="40" cx="48" cy="48" fill="none" stroke-miterlimit="20" stroke-width="10" style="stroke-dasharray: 251, 279.602;stroke:#fdd835;">
</circle>
</svg>
这里我们通过控制 svg 的 stroke-dasharray 属性值来达到控制圆环进度的变化
动态变化的属性值通过 props 将进度值传递到组件里面,使用 watch 监听值的变化,这样圆环进度条功能就实现了,下面来看具体的实现过程。
<div class="progress" :style="{width, height}">
<svg viewBox="0 0 96 96" class="svg-circle-progress" style="width: 96px; height: 96px;">
<circle r="40" cx="48" cy="48" fill="none" stroke-miterlimit="20" stroke-width="10" class="svg-progress"
style="stroke-dasharray: 275, 279.602;stroke:#eee;">
</circle>
<circle r="40" cx="48" cy="48" fill="none" stroke-miterlimit="20" stroke-width="10"
class="svg-progress"
:style="`stroke-dasharray: ${progressValue}, 279.602;stroke:${color};`">
</circle>
</svg>
</div>
<script setup>
import { ref, toRefs, watch } from 'vue'
const props = defineProps({
progress: {
type: Number,
default: () => 20
},
color: {
type: String,
default: () => "#FFAFAF"
},
width: {
type: String,
default: () => "210px"
},
height: {
type: String,
default: () => "100px"
},
})
const { height, width, color, progress } = toRefs(props)
const progressValue = ref((progress.value / 100) * 250)
watch(progress, (newValue) => {
progressValue.value = (newValue / 100) * 250
})
</script>
<style lang="css" scoped>
.progress {
display: inline-block;
position: relative;
height: 100px;
text-align: center;
}
.svg-circle-progress {
position: relative;
transform: rotate(-90deg);
}
.svg-progress {
stroke: #2196f3;
stroke-linecap: round;
transition: all .3s linear;
}
</style>
圆环进度条的宽高属性,进度值,进度条的颜色我们设置一个默认值,可以自定义,同时优化下进度条的样式。
除了进度条的变化,我们还需要显示进度值,在 svg 后面我们添加如下代码
<div class="mask">
{{ progress}}%
</div>
同时添加进度值的样式
.mask {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
接着我们在 App.vue 组件中将进度条组件引入,声明一个进度值,并赋值1到100的随机值,放在定时器中,动态变化
<template>
<div class="">
<CircleProgress :progress="progress" color="#fdd835" />
</div>
</template>
<script setup>
import { ref } from "vue"
import CircleProgress from "./components/circleProgress.vue";
const progress = ref(50)
setInterval(() => {
progress.value = Math.floor(Math.random()*100+1)
}, 1000);
</script>