☰
微信小程序:计时器
2026/10/14 18:43:02 网站建设 项目流程

最终效果

页面加载后延迟 2 秒显示计时器主体,中间是一个大号数字(从 60 开始倒数),下方是三个按钮:开始计时、停止计时、重新计时。整体结构非常简洁,一个页面就能搞定。

一、页面结构(WXML)

先来看页面骨架:

<navigation-bar title="计时器" back="{{false}}" color="black" background="#FFF"></navigation-bar> <scroll-view class="scrollarea" scroll-y type="list"> <view class="box" hidden="{{hidden}}"> <view class="title">计时器函数的应用</view> <view class="time">{{num}}</view> <view class="btn-layout"> <button type="primary" size="mini" bind:tap="start">开始计时</button> <button type="primary" size="mini" bind:tap="stop">停止计时</button> <button type="primary" size="mini" bind:tap="restart">重新计时</button> </view> </view> </scroll-view>

结构上分三层:

1. 自定义导航栏组件`navigation-bar` ,设置标题为"计时器",隐藏返回按钮;

2. 中间用`{{num}}` 做数据绑定,实时显示当前秒数;

3. 三个按钮分别通过`bind:tap` 绑定`start` 、`stop` 、`restart` 三个事件处理函数。

另外注意`hidden="{{hidden}}"` 这个属性,它控制整个计时器区域的显示与隐藏,后面会用到它来做延迟入场的效果。

二、核心逻辑(JS)

let num = 60 let isTime = true let timerId Page({ data: { hidden: true, num }, onLoad() { setTimeout(() => { this.show() }, 2000) }, show() { this.setData({ hidden: false }) }, start() { if (isTime) { timerId = setInterval(() => { this.timer() }, 1000) } }, timer() { this.setData({ num }) if (num > 0) { num-- } else { clearInterval(timerId) isTime = false } }, stop() { clearInterval(timerId) isTime = true }, restart() { clearInterval(timerId) isTime = true num = 60 this.setData({ num }) this.start() } })

1. 三个模块级变量

这里把`num` (当前秒数)、`isTime` (是否允许开启定时器的标志位)、`timerId` (定时器句柄)定义在了`Page` 外面,作为模块级变量。这样做的原因是它们属于"计时器状态"而不是"渲染数据"——当然`num` 同时要渲染到页面上,所以在`data` 里也放了一份初始值。

2. 延迟 2 秒显示

`onLoad` 里用`setTimeout` 延迟 2 秒调用`show()` ,把`hidden` 置为`false` ,实现了一个简单的入场效果。配合 WXML 里的`hidden="{{hidden}}"` ,页面打开时先留白,2 秒后计时器才出现。

3. start:防止重复开启定时器

start() { if (isTime) { timerId = setInterval(() => { this.timer() }, 1000) } }

`isTime` 这个标志位非常关键。如果没有它,用户连续点击"开始计时"会创建多个定时器叠加,倒计时速度会越来越快。有了这个标志位,只有当上一个定时器被清除(`stop` 或倒计时结束)后才能再次开启。

还有一个细节:`setInterval` 的回调使用了 箭头函数 ,这样回调内部的`this` 才能正确指向 Page 实例,才能调用`this.timer()` 。如果写成普通函数,`this` 会指向`undefined` (严格模式下)。

4. timer:每秒做的事

timer() { this.setData({ num }) if (num > 0) { num-- } else { clearInterval(timerId) isTime = false } }

每秒执行一次:先把当前秒数同步到视图层,然后判断是否还能继续减。当`num` 减到 0 时,主动`clearInterval` 清除定时器。 一定要记得清除定时器 ,否则它会一直空转,造成内存泄漏。

5. stop 和 restart

停止很简单:清掉定时器,并把`isTime` 恢复为`true` ,允许下次开启。

重置在停止的基础上多做两步:把`num` 恢复成 60 并更新视图,然后直接调用`start()` 重新开启倒计时。

三、样式(WXSS)

.time { width: 90%; background-color: rgb(145, 145, 221); color: rgb(228, 20, 20); font-size: 200rpx; text-align: center; border: 2rpx solid red; border-radius: 60rpx; margin: 30rpx; position: relative; } .time::before { content: "一寸光阴一寸金"; position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%); color: #731717; font-size: 32rpx; }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询