IT俱乐部 JavaScript 使用Vue3实现倒计时器及倒计时任务的完整代码

使用Vue3实现倒计时器及倒计时任务的完整代码

本内容使用Vue3,以及element-plus辅助开发。

首先展示倒计时器的功能:

  • 手动设置倒计时器的倒计时时间
  • 开始倒计时按钮
  • 暂停倒计时按钮
  • 重新开始倒计时按钮

 其次展示倒计时任务管理界面功能:

创建倒计时任务选择任务并进行倒计时删除任务

一.倒计时器:

最后面会附有完整代码,可直接CV。 

1.html:

使用element-plus下拉框组件选择设置的时分秒的时间,点击确定按钮就可以将设置的时间在formattedTime显示,随后使用操作按钮进行对计时器的操作。 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<h2>倒计时器</h2>
     
    <div>
        确定
</div>                  
     
    <div class="timer-display">
        <h1>{{ formattedTime }}</h1>
    </div>
     
    <div class="controls">
         
        开始暂停重新开始下一阶段
</div>

 2.script:

(1)状态变量:

1
2
3
4
5
6
7
8
9
10
// 选择的倒计时初始值
const selectedHours = ref(0);
const selectedMinutes = ref(0);
const selectedSeconds = ref(0);
// 当前剩余的倒计时时间,以秒为单位动态更新
const totalSeconds = ref(0);
// 表示倒计时是否正在运行,用来防止重复启动计时器
const isRunning = ref(false);
// 存储定时器的句柄,用于管理 setInterval
let timer = null;

(2)格式化显示时间:

1
2
3
4
5
6
7
8
// computed:这是一个计算属性,动态计算剩余时间的格式化显示。
const formattedTime = computed(() => {
    const hours = Math.floor(totalSeconds.value / 3600);
    const minutes = Math.floor((totalSeconds.value % 3600) / 60);
    const seconds = totalSeconds.value % 60;
    // 返回格式用于倒计时器的显示 hh:mm:ss
    return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
});

格式化逻辑

  • 小时Math.floor(totalSeconds.value / 3600),将总秒数除以3600得到小时数(向下取整)。
  • 分钟:取余后计算分钟数:Math.floor((totalSeconds.value % 3600) / 60)
  • 秒数:取余后直接取 totalSeconds.value % 60
  • 格式化:使用 padStart(2, '0') 保证个位数前补 0,显示为两位数。

 (3)初始化倒计时:

1
2
3
4
// 将计算结果赋值给 totalSeconds,作为倒计时的起始值。
const initializeCountdown = () => {
    totalSeconds.value = selectedHours.value * 3600 + selectedMinutes.value * 60 + selectedSeconds.value;
};

(4)开始按钮startCountdown -> 启动倒计时器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const startCountdown = () => {
    if (totalSeconds.value === 0) {
        initializeCountdown(); // 如果总秒数为0,重新初始化
    }
    // 通过 isRunning 确保倒计时只能启动一次
    if (!isRunning.value) {
        isRunning.value = true;
        // 使用 setInterval 每秒执行一次回调
        timer = setInterval(() => {
            if (totalSeconds.value > 0) {
                totalSeconds.value -= 1; // 每秒减1
            } else {
                // 调用 pauseCountdown 停止计时器
                pauseCountdown();
            }
        }, 1000);
    }
};

(5)暂停按钮pauseCountdown -> 暂停倒计时器:

1
2
3
4
5
6
7
8
9
const pauseCountdown = () => {
    // 将 isRunning 设置为 false,标记倒计时暂停
    isRunning.value = false;
    // 如果计时器已存在(timer 不为 null),调用 clearInterval 停止计时器,并将 timer 置空
    if (timer) {
        clearInterval(timer);
        timer = null;
    }
};

(6)重启倒计时器restartCountdown -> 重新开始倒计时:

1
2
3
4
5
6
7
8
const restartCountdown = () => {
    // 停止当前计时器
    pauseCountdown();
    // 重置 totalSeconds 为初始值
    initializeCountdown();
    // 重新启动倒计时
    startCountdown();
};

(7)确定按钮 -> 修改倒计时时间:

1
2
3
4
5
// 停止当前计时器,重新计算并设置倒计时总秒数
const getTrue = () => {
    pauseCountdown();
    initializeCountdown();
};

(8)页面卸载时清理计时器(onUnMounted):

1
2
3
4
5
6
7
// 当组件卸载时触发
onUnmounted(() => {
    // 清理计时器,防止内存泄漏
    if (timer) {
        clearInterval(timer);
    }
});

 3.css:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.countdown-timer {
    text-align: center;
    font-family: Arial, sans-serif;
}
.timer-display h1 {
    font-size: 48px;
    margin: 20px 0;
}
.controls button {
    margin: 5px;
    padding: 10px 20px;
    font-size: 16px;
}
select {
    margin: 5px;
    padding: 5px;
}

二.倒计时任务管理界面:

通过弹窗填写任务名称和时间(时、分、秒),并将任务提交到任务列表中。 

1.html:

1
2
3
4
创建任务<h3>任务队列</h3>
    <div class="dialog-footer">
            取消创建任务
</div>

2.script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// 用于控制弹窗的显示和隐藏状态
const taskDialogVisible = ref(false);
// 打开弹窗
const addTaskDialog = () =>{
    taskDialogVisible.value = true;
    console.log('弹窗状态:', taskDialogVisible.value); // 调试日志
}
// 用于绑定用户输入的任务数据
const newTask = reactive({
    name: '', // 任务名称
    // 用户输入的时、分、秒,表示任务的时间
    hours: '',
    minutes: '',
    seconds: ''
})
// 任务列表
const timeTaskData = ref([]);
const timeTask = reactive({
    name: "",
    time: null, // 任务时间,格式为 HH:mm:ss
    roomGroup : ""
});
// 清空 timeTask 中的任务数据
const cleantimeRask = () =>{
    timeTask.value = {
        name: "",
        time: null,
        roomGroup : ""
    };
}
const addTimeTask = async () =>{
    taskDialogVisible.value = false;
    // 使用用户输入的时、分、秒来设置时间
    const hours = parseInt(newTask.hours) || 0;
    const minutes = parseInt(newTask.minutes) || 0;
    const seconds = parseInt(newTask.seconds) || 0;
    // 将时间合并为 HH:mm:ss 格式
    const timeString = `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
    // 设置任务数据
    timeTask.time = timeString; // 使用标准的 HH:mm:ss 格式
    // 从 userStore 获取当前用户的分组
    timeTask.roomGroup = userStore.user.roomGroup;
    timeTask.name = newTask.name;
    if (timeTask.name !== '' && timeTask.time !== '') {
        await insertTimeTask(timeTask); // 插入任务(异步操作)
        ElMessage.success("任务添加成功");
        getTimeTaskByRGToShow(); // 更新任务列表
        console.log(timeTaskData.value);
        cleantimeRask(); // 清空当前任务数据
    } else {
        ElMessage.error("任务名称或时间不能为空");
    }
}
// 设置倒计时的时、分、秒
const setCountdownTime = (row) => {
    let date;
    if (row.time instanceof Date) {
        date = row.time; // 如果是 Date 对象,直接赋值
    } else if (typeof row.time === "string") {
        const [hours, minutes, seconds] = row.time.split(":").map(Number); // 按 HH:mm:ss 分割
        date = new Date(); // 使用当前日期
        date.setHours(hours, minutes, seconds); // 设置时间
    } else {
        console.error("无效的时间格式");
        return;
    }
    selectedHours.value = date.getHours();      // 获取小时
    selectedMinutes.value = date.getMinutes();  // 获取分钟
    selectedSeconds.value = date.getSeconds();  // 获取秒数
    initializeCountdown(); // 更新总时间
};
// 删除倒计时的任务
const deleteTimeTask = async (row) =>{
    await deleteTimeTaskById(row.id);
    ElMessage.success("任务删除成功");
    getTimeTaskByRGToShow();
    console.log(timeTaskData.value);
};
// 根据组别获取所有任务信息
const getTimeTaskByRGToShow = async () =>{
    let roomGroup = userStore.user.roomGroup;
    let result = await getTimeTaskByRG(roomGroup);
    timeTaskData.value = result.data;
}
getTimeTaskByRGToShow();

三.倒计时器完整代码展示:

1.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<div>
        创建任务<h3>任务队列</h3>
             
</div>
    <div class="countdown-timer">
        <h2>倒计时器</h2>
             
            <div>
                确定
</div>                  
             
            <div class="timer-display">
                <h1>{{ formattedTime }}</h1>
            </div>
             
            <div class="controls">
                 
                开始暂停重新开始下一阶段
</div>
         
</div>
<div class="dialog-footer">
            取消创建任务
</div>

2.script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import { reactive, ref, computed, onUnmounted } from 'vue';
import {  Check,Delete,Star } from '@element-plus/icons-vue';
import { getCpByRG, insertByRG } from '@/api/competition';
import { getTimeTaskByRG,insertTimeTask,deleteTimeTaskById } from '@/api/timetask';
import { useUserStore } from '@/stores/user';
import { ElMessage } from 'element-plus';
const userStore = useUserStore();
// 弹窗组件
const taskDialogVisible = ref(false);
const addTaskDialog = () =>{
    taskDialogVisible.value = true;
    console.log('弹窗状态:', taskDialogVisible.value); // 调试日志
}
const newTask = reactive({
    name: '',
    hours: '',
    minutes: '',
    seconds: ''
})
const timeTaskData = ref([]);
const timeTask = reactive({
    name: "",
    time: null,
    roomGroup : ""
});
const cleantimeRask = () =>{
    timeTask.value = {
        name: "",
        time: null,
        roomGroup : ""
    };
}
const addTimeTask = async () =>{
    taskDialogVisible.value = false;
    // 用用户输入的时、分、秒来设置时间
    const hours = parseInt(newTask.hours) || 0;
    const minutes = parseInt(newTask.minutes) || 0;
    const seconds = parseInt(newTask.seconds) || 0;
    // 将时间合并为 HH:mm:ss 格式
    const timeString = `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
    // 设置任务数据
    timeTask.time = timeString; // 使用标准的 HH:mm:ss 格式
    timeTask.roomGroup = userStore.user.roomGroup;
    timeTask.name = newTask.name;
    if (timeTask.name !== '' && timeTask.time !== '') {
        await insertTimeTask(timeTask);
        ElMessage.success("任务添加成功");
        getTimeTaskByRGToShow();
        console.log(timeTaskData.value);
        cleantimeRask();
    } else {
        ElMessage.error("任务名称或时间不能为空");
    }
}
// 设置倒计时的时、分、秒
const setCountdownTime = (row) => {
    let date;
    if (row.time instanceof Date) {
        date = row.time; // 如果是 Date 对象,直接赋值
    } else if (typeof row.time === "string") {
        const [hours, minutes, seconds] = row.time.split(":").map(Number); // 按 HH:mm:ss 分割
        date = new Date(); // 使用当前日期
        date.setHours(hours, minutes, seconds); // 设置时间
    } else {
        console.error("无效的时间格式");
        return;
    }
    selectedHours.value = date.getHours();      // 获取小时
    selectedMinutes.value = date.getMinutes();  // 获取分钟
    selectedSeconds.value = date.getSeconds();  // 获取秒数
    initializeCountdown(); // 更新总时间
};
// 删除倒计时的任务
const deleteTimeTask = async (row) =>{
    await deleteTimeTaskById(row.id);
    ElMessage.success("任务删除成功");
    getTimeTaskByRGToShow();
    console.log(timeTaskData.value);
};
// 根据组别获取所有任务信息
const getTimeTaskByRGToShow = async () =>{
    let roomGroup = userStore.user.roomGroup;
    let result = await getTimeTaskByRG(roomGroup);
    timeTaskData.value = result.data;
}
getTimeTaskByRGToShow();
/
// 倒计时器
// 选择的倒计时初始值
const selectedHours = ref(0);
const selectedMinutes = ref(0);
const selectedSeconds = ref(0);
// 当前倒计时时间(以秒为单位)
const totalSeconds = ref(0);
const isRunning = ref(false);
let timer = null;
// 格式化显示的时间
const formattedTime = computed(() => {
    const hours = Math.floor(totalSeconds.value / 3600);
    const minutes = Math.floor((totalSeconds.value % 3600) / 60);
    const seconds = totalSeconds.value % 60;
    return `${String(hours).padStart(2, '0')}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;
});
// 初始化倒计时
const initializeCountdown = () => {
    totalSeconds.value = selectedHours.value * 3600 + selectedMinutes.value * 60 + selectedSeconds.value;
};
// 开始倒计时
const startCountdown = () => {
    // 如果当前总秒数为 0,自动初始化倒计时
    if (totalSeconds.value === 0) {
        initializeCountdown();
    }
    if (!isRunning.value) {
        isRunning.value = true;
        playSound('start'); // 播放开始音效
        timer = setInterval(() => {
            if (totalSeconds.value > 0) {
                totalSeconds.value -= 1;
            } else {
                pauseCountdown();
                playSound('end'); // 倒计时结束时播放音效
            }
        }, 1000);
    }
};
// 暂停倒计时
const pauseCountdown = () => {
    isRunning.value = false;
    playSound('pause'); // 播放暂停音效
    if (timer) {
        clearInterval(timer);
        timer = null;
    }
};
// 重新开始倒计时
const restartCountdown = () => {
    pauseCountdown();
    initializeCountdown();
    playSound('reset'); // 播放重置音效
    startCountdown();
};
// 确定修改倒计时时间
const getTrue = () => {
    pauseCountdown();
    initializeCountdown();
};
// 页面卸载时清理计时器
onUnmounted(() => {
    if (timer) {
    clearInterval(timer);
    }
});

3.css:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.countdown-timer {
    text-align: center;
    font-family: Arial, sans-serif;
}
.timer-display h1 {
    font-size: 48px;
    margin: 20px 0;
}
.controls button {
    margin: 5px;
    padding: 10px 20px;
    font-size: 16px;
}
select {
    margin: 5px;
    padding: 5px;
}

到此这篇关于使用Vue3来实现一个倒计时器以及倒计时任务的文章就介绍到这了,更多相关vue3倒计时内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!

本文收集自网络,不代表IT俱乐部立场,转载请注明出处。https://www.2it.club/navsub/js/14206.html
上一篇
下一篇
联系我们

联系我们

在线咨询: QQ交谈

邮箱: 1120393934@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部