使用uni-app制作的番茄时钟

3,362 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情

前言

这个番茄时钟是我从我自己开发维护的备考小程序里单独拿出来的一个模块,功能尚不完善,仅有设置目标倒计时、计时、结束计时三个功能,因此我自己认为可塑性较大,稍微增加一些自己的主观想法就是一个新的东西。

过几天我可能会把剩下两个模块一起拿出来😁

效果图

屏幕截图 2022-07-30 112049.png

屏幕截图 2022-07-30 113015.png

注意:下方的tabBar在该模块中不存在,需要自己去json文件中配置

完整代码

<template>
	<view class="content">
		<view class="title fontS46">
			番茄工作<br>
			<text class="title-child fontS24">切换到别的位置也能继续计时</text>
		</view>
		<view class="img">
			<image src="../../static/img/tomato.png" class="tomato" @tap="getIntroduce"></image>
		</view>
		<view>
			<view class="time-num">
				<picker mode="multiSelector" :range="range" @change="changeTomato">
					<view>{{countDown}}</view>
				</picker>
			</view>
		</view>
		<view class="time">
			<button type="primary" @tap="start" v-show="!tomatoStart">开始</button>
			<view class="started" v-show="tomatoStart">
				<button @tap="end">结束</button>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				min: '25',
				sec: '00',
				tomatoStart: false,
				timer: ''
			}
		},
		computed: {
			range() {
				let arr = []
				let arr1 = []
				for (let i = 0; i < 60; i++) {
					let num = i
					num = this.addZero(num)
					arr1.push(num)
				}
				arr = [arr1, arr1]
				return arr
			},
			countDown() {
				return `${this.min}:${this.sec}`
			}
		},
		methods: {
			getIntroduce() {
				uni.navigateTo({
					url: '../tomatoIntroduce/tomatoIntroduce' //跳转
				})
			},
			changeTomato(e) {
				console.log(e.detail.value);
				this.min = this.addZero(e.detail.value[0])
				this.sec = this.addZero(e.detail.value[1])
			},
			addZero(num) {
				if (num < 10) {
					num = '0' + num
				}
				return num
			},
			startTimer() {
				this.timer = setInterval(() => {
					if (this.sec != '00') {
						let sec = Number(this.sec)
						sec -= 1
						this.sec = this.addZero(sec)
					} else if (this.sec == '00' && this.min != '00') {
						let min = Number(this.min)
						min -= 1
						this.sec = '59'
						this.min = this.addZero(min)
					} else if (this.sec == '00' && this.min == '00') {
						clearInterval(this.timer)
						uni.vibrateLong({
							success() {
								setTimeout(() => {
									uni.vibrateLong({

									})
								}, 500)
							}
						})
						this.getLocal()
						this.tomatoStart = false
						uni.showModal({
							title:'恭喜',
							content:'你刚刚完成了一个番茄,建议休息5分钟后再开启下一个番茄',
							showCancel:false
						})
					}
				}, 1000)
			},
			start() {
				let tomato = {
					min: this.min,
					sec: this.sec
				}
				uni.setStorage({
					key: 'tomato',
					data: tomato
				})
				this.tomatoStart = true
				this.startTimer()
			},
			end() {
				let that = this
				clearInterval(this.timer)
				uni.showModal({
					content: '确定结束?',
					success(response) {
						if (response.confirm) {
							that.getLocal()
							that.tomatoStart = false
						} else if (response.cancel) {
							that.startTimer()
						}
					},
				})
			},
			getLocal(){
				let that = this
				uni.getStorage({
					key: 'tomato',
					success(response) {
						let time = response.data
						that.min = time.min
						that.sec = time.sec
					}
				})
			}
		}
	}
</script>

<style>
	.tomato {
		width: 400upx;
		height: 400upx;
	}

	.title {
		text-align: center;
	}
	
	.title-child{
		color: #707070;
	}

	.time-num {
		text-align: center;
		font-size: 100upx;
	}

	.started button {
		float: left;
		margin: 10upx;
	}
</style>

以下代码存放于与上述代码同级目录下

且文件名为tomatoIntroduce(不一定非得是这个名字,上面的代码中我已用"//跳转"标记出用到下方代码的地方)

<template>
	<view>
		<uni-card title="番茄工作法" extra="摘自百度百科">
			番茄工作法是简单易行的时间管理方法。<br>
			使用番茄工作法,选择一个待完成的任务,将番茄时间设为25分钟,专注工作,中途不允许做任何与该任务无关的事,直到番茄时钟响起,然后进行短暂休息一下(5分钟就行),然后再开始下一个番茄。每4个番茄时段多休息一会儿。<br>
			番茄工作法极大地提高了工作的效率,还会有意想不到的成就感。
		</uni-card>
	</view>
</template>

<script>

</script>

<style>

</style>

以下是一个全局css样式(uni.scss文件中)

.content {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: space-around;
	height: 100vh;
}

食用指南

食用须知

  • 在所有html的class属性中,若出现fontS46等以 fontS+数字 组合的class样式,则代表这是一个全局css样式,且样式都是在设置font-size,例如:fontS46的样式是font-size: 46upx;以此类推,注意单位是upx这是一个为了方便适配不同设备大小而出现的单位。
  • 对于上述代码中的全局css样式,该class样式用在所有tabBar所控制的路由组件的最外侧容器上,用来更为方便地使控制容器,使其占据整个屏幕,且使用flex布局可以更方便地适配不同设备,但是因为使用了100vh来控制height属性,所以在浏览器中可能高度会超过整个屏幕(可上下滑动),但是发布到在微信小程序后不存在上述情况。
  • 中间的那个大大的番茄图标是我从iconfont中下载的png图片,样式已经调好了,尊重一下原创作者我这里就不发了,不用这个图的话直接找一个正方形的图片代替就可以

执行过程解读

picker标签

  • 默认一个番茄的时间是25:00,也就是25分钟一个番茄,当用户点击这个时间时将会在下方弹出一个选择器。
  • 选择器是picker标签,mode属性填入了multiSelector,表示该选择器为一个多列选择器(由于一个开发中的bug让我发现这个维数似乎无上限),range属性可传入一个多维数组,每一维表示选择器中的一个维度,例如[ ["北京", "上海", "广州"], [ 1, 2, 3] ]表示一个picker选择器中有两个维度,第一个维度中有三个选项分别是北京 上海 广州,第二个维度中有三个选项分别是1 2 3.
  • 本组件中的picker选择器中的range传入的是一个computed中的range()所返回的数组,range()中已经使用for循环创建好了一个二维数组,其两个维度都是"00"~"59"的数组.
  • 关于picker详细内容请看官方文档:uniapp.dcloud.net.cn/component/p…

开始后

  • 在用户点击开始后,则调用start函数,获取用户所设置的时间,将该时间拆分为两部分:min、sec用于表示分钟、秒钟,然后将其存于本地缓存中等待下一次调用。
  • 在用户点击开始后,将tomatoStart设置为true表示已经开始计时,该变量控制了html下方的两个按钮“开始”和“结束”的显示与隐藏
  • start函数的最后会调用startTimer函数,该函数会启动计时器以开始倒计时,当秒针sec变成"00"时,分钟min将会-1且sec会改成59。
  • addZero是一个复用度比较高的一个函数,只有补零的作用:当传入数值<=9 时,在该数值的前面加一个"0"
  • 开始计时后,受变量tomatoStart控制的结束按钮被显示且开始按钮隐藏,点击结束按钮后调用end函数,取出本地缓存中表示用户所设置的倒计时数据并渲染到页面中以完成计时重置
  • 因为番茄工作法中时间不能暂停,所以没有添加暂停功能