vue实现打卡进度组件
Vue 打卡进度组件实现
核心思路
通过动态计算已完成天数与总天数的比例,结合 CSS 动画或过渡效果,实现进度条或日历形式的打卡可视化。
基础进度条实现
模板部分
<template>
<div class="progress-container">
<div class="progress-bar" :style="{ width: progress + '%' }"></div>
<span>{{ progress }}% 已完成</span>
</div>
</template>
脚本部分
<script>
export default {
props: {
totalDays: { type: Number, default: 30 },
completedDays: { type: Number, default: 0 }
},
computed: {
progress() {
return Math.round((this.completedDays / this.totalDays) * 100);
}
}
};
</script>
样式部分
<style scoped>
.progress-container {
width: 100%;
height: 20px;
background-color: #f0f0f0;
border-radius: 10px;
position: relative;
}
.progress-bar {
height: 100%;
background-color: #4caf50;
border-radius: 10px;
transition: width 0.3s ease;
}
</style>
日历打卡形式实现
模板部分
<template>
<div class="calendar-grid">
<div
v-for="day in totalDays"
:key="day"
class="day-cell"
:class="{ 'completed': day <= completedDays }"
></div>
</div>
</template>
样式部分
<style scoped>
.calendar-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 8px;
}
.day-cell {
width: 30px;
height: 30px;
background-color: #e0e0e0;
border-radius: 4px;
}
.day-cell.completed {
background-color: #4caf50;
}
</style>
动画增强效果
添加点击动画
在日历形式中增加点击反馈:
.day-cell {
transition: transform 0.2s;
}
.day-cell:active {
transform: scale(0.9);
}
进度条加载动画
.progress-bar {
animation: pulse 1.5s infinite;
}
@keyframes pulse {
0% { opacity: 1; }
50% { opacity: 0.7; }
100% { opacity: 1; }
}
进阶功能扩展
持久化存储
结合 localStorage 保存打卡状态:
mounted() {
const savedProgress = localStorage.getItem('progress');
if (savedProgress) {
this.completedDays = parseInt(savedProgress);
}
},
methods: {
handleDayClick(day) {
if (day === this.completedDays + 1) {
this.completedDays++;
localStorage.setItem('progress', this.completedDays);
}
}
}
节日特殊样式
通过日期判断添加特殊样式:
computed: {
dayClass() {
return (day) => ({
'holiday': this.isHoliday(day),
'completed': day <= this.completedDays
});
}
}
注意事项
- 移动端适配需调整单元格大小和间距
- 国际化场景需动态显示周数/月份
- 大量天数时建议使用虚拟滚动优化性能
- 颜色方案可通过 CSS 变量实现主题切换
以上实现可根据实际需求组合使用,例如同时显示进度条和日历,或添加徽章奖励等激励元素。







