Appearance
实现 番茄钟 工具
分类:developer | 标签:番茄钟、专注、时间管理、效率 番茄工作法专注/休息循环,可配置时长,统计完成番茄数
2.1 功能说明
番茄工作法专注/休息循环,可配置时长,统计完成番茄数
2.1.1 使用指南
使用指导
番茄工作法:专注一段时间(默认 25 分钟),休息一段时间(默认 5 分钟),每完成 4 个番茄自动进入长休息。
建议
一个番茄时间内只做一件事;休息时起身活动,保护视力和颈椎。
2.2 代码实现
2.2.1 组件结构
本工具是一个基于 Vue 3 <script setup> 语法的单文件组件(SFC),统一包裹在 ToolPageShell 组件内,由它提供页面标题、工具 ID、分类与「使用指南」插槽等通用外壳;核心业务逻辑(响应式状态、计算属性、事件处理函数)全部写在 <script setup> 中,输入/输出通过 el-input、el-button 等 Element Plus 组件与用户交互,所有数据均在浏览器本地处理,不会上传服务器。
2.2.2 核心逻辑概览
<script setup> 中定义的主要函数/方法:
fmtTime()toggle()tick()nextPhase()skip()reset()
2.2.3 关键实现代码
以下是该工具的完整 <script setup> 实现(核心代码)。模板(<template>)与样式(<style>)已省略。
vue
import { ref, computed, onUnmounted } from 'vue'
import ToolPageShell from '@/components/ToolPageShell.vue'
const workMin = ref(25)
const breakMin = ref(5)
const longMin = ref(15)
const phase = ref('work')
const remain = ref(workMin.value * 60)
const running = ref(false)
const completed = ref(0)
let timer = null
const circ = 2 * Math.PI * 90
const total = computed(() => (phase.value === 'work' ? workMin.value : phase.value === 'break' ? breakMin.value : longMin.value) * 60)
const offset = computed(() => circ * (1 - remain.value / total.value))
const ringColor = computed(() => phase.value === 'work' ? '#3883fa' : phase.value === 'long' ? '#67c23a' : '#e6a23c')
const phaseText = computed(() => ({ work: '专注', break: '短休息', long: '长休息' }[phase.value]))
function fmtTime(sec) {
sec = Math.max(0, Math.floor(sec))
const mm = String(Math.floor(sec / 60)).padStart(2, '0')
const ss = String(sec % 60).padStart(2, '0')
return `${mm}:${ss}`
}
function toggle() {
running.value = !running.value
if (running.value) timer = setInterval(tick, 1000)
else clearInterval(timer)
}
function tick() {
remain.value--
if (remain.value <= 0) {
if (phase.value === 'work') completed.value++
nextPhase()
}
}
function nextPhase() {
if (phase.value === 'work') {
phase.value = completed.value % 4 === 0 ? 'long' : 'break'
} else {
phase.value = 'work'
}
remain.value = total.value
}
function skip() {
clearInterval(timer); running.value = false
nextPhase()
}
function reset() {
clearInterval(timer); running.value = false
remain.value = (phase.value === 'work' ? workMin.value : phase.value === 'break' ? breakMin.value : longMin.value) * 60
}
onUnmounted(() => clearInterval(timer))2.3 效果截图
