小知识,大挑战!本文正在参与“ 程序员必备小知识 ”创作活动
本文同时参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金
前言
佛祖保佑, 永无bug。Hello 大家好!我是海的对岸!
这个组件也算是一个通用的组件,在此记录一下。
实现
效果
原理
原理很简单,大概撸一遍
- 获取
当前时间(时分秒) - 一天24小时
减去获取的当前时间,得到倒计时时间 - 对
倒计时时间进行时分秒的判断,如果时分秒是一位数,那么需要在前面补0 - 把处理好的倒计时时间显示出来
- 用
计时器接着进行步骤1 继续走
上代码:
<template>
<div class="number-grow-warp">
<span >{{time}}</span>
</div>
</template>
<script>
export default {
data() {
return {
time: '24:00:00',
timer: undefined, // 计时器,作用:组件销毁的时候需要把定时器清除
}
},
mounted() {
this.start(); // 24小时倒计时
},
methods: {
// 获取当前时间的24小时倒计时
countDown() {
let now = new Date(); // 获取当前时间
let hour = now.getHours(); // 时
let min = now.getMinutes(); // 分
let sec = now.getSeconds(); // 秒
let result = ''; // 返回结果
let h = 24 - hour; // 一天中剩下的时间(小时)
if (min > 0 || sec > 0) {
h -= 1
}
let m = 60 - min; // 一天中剩下的时间(分钟)
if (sec > 0) {
m -= 1
}
if (m == 60) {
m = 0
}
let s = 60 - sec; // 一天中剩下的时间(秒)
if (s == 60) {
s = 0
}
h = h.toString();
m = m.toString();
s = s.toString();
if (h.length == 1) { // 补0
h = '0' + h
}
if (m.length == 1) { // 补0
m = '0' + m
}
if (s.length == 1) // 补0
s = '0' + s
result = h + ':' + m + ':' + s
return result
},
start() {
this.timer = setInterval(function () {
this.time = this.countDown();
}, 1000)
},
},
destroyed() {
clearInterval(this.timer); // 组件销毁时清除定时器
},
}
</script>
<style scoped>
</style>
计时器的方法没有问题,但是页面上并没有显示出倒计时,细心的大家有没有看出问题在哪里?
问题在setInterval这个函数上,这就引出了vue的this 和 function的this中间的出入了
vue的this 和 function的this
vue中的this:
- 很好理解,这个
this指向的就是vue对象。比如,你在motheds中写了几个方法(xx1(), xx2(), ...),在mounted或created,或watch等钩子中使用,都可以直接this.xx1(),直接调用方法
function的this:
- 这个
this指向window 普通函数中的this指向是变化的,谁调用的指向谁,因为setInterval和setTimeout是挂载在window上的,相当于window.setInterval和window.setTimeout,所以执行函数中的this指向window- 那
箭头函数呢?箭头函数中的this指向是固定不变(定义函数时的指向)
解决this的问题
同样是上面的代码,改动的地方就在start()中
- 方法1
- 用
箭头函数(简单粗暴)
start() {
setInterval(() => {
this.time = this.countDown();
}, 1000)
}
试验下直接在start()中不使用箭头函数呢?答案是undefined
start() {
setInterval(function() {
console.log(this.time); // 打印出undefined
}, 1000)
}
- 方法2
- 用
setInterval和setTimeout的第三个参数 - 原理:
setInterval和setTimeout的第三个参数可以作为执行函数的参数,具体用法看下文代码
start() {
setInterval(
_this => {
console.log(_this.time); // 打印出具体时间
_this.time = this.countDown();
},
500,
this
);
}
- 保存一下
this
start() {
let that = this;
setInterval(() => {
console.log(that.time); // 打印出具体时间
that.time = this.countDown();
}, 500);
}
最后完整代码
com24hourCountDown.vue
<template>
<div class="number-grow-warp">
<span ref="time">{{time}}</span>
</div>
</template>
<script>
export default {
data() {
return {
time: '24:00:00',
timer: undefined, // 计时器,作用:组件销毁的时候需要把定时器清除
}
},
mounted() {
this.start(); // 24小时倒计时
},
methods: {
// 获取当前时间的24小时倒计时
countDown() {
let now = new Date(); // 获取当前时间
let hour = now.getHours(); // 时
let min = now.getMinutes(); // 分
let sec = now.getSeconds(); // 秒
let result = ''; // 返回结果
let h = 24 - hour; // 一天中剩下的时间(小时)
if (min > 0 || sec > 0) {
h -= 1
}
let m = 60 - min; // 一天中剩下的时间(分钟)
if (sec > 0) {
m -= 1
}
if (m == 60) {
m = 0
}
let s = 60 - sec; // 一天中剩下的时间(秒)
if (s == 60) {
s = 0
}
h = h.toString();
m = m.toString();
s = s.toString();
if (h.length == 1) { // 补0
h = '0' + h
}
if (m.length == 1) { // 补0
m = '0' + m
}
if (s.length == 1) // 补0
s = '0' + s
result = h + ':' + m + ':' + s
return result
},
start() {
setInterval(() => {
this.time = this.countDown();
}, 1000)
// 测试1
// setInterval(function() {
// console.log(this.time); // undefined
// }, 500);
// 测试2
// setInterval(() => {
// console.log(this.time); // 具体时间
// }, 500);
// 测试3
// setInterval(
// _this => {
// console.log(_this.time); // 具体时间
// _this.time = this.countDown();
// },
// 500,
// this
// );
// 测试4
// let that = this;
// setInterval(() => {
// console.log(that.time);// 具体时间
// that.time = this.countDown();
// }, 500);
},
},
destroyed() {
clearInterval(this.timer); // 组件销毁时清除定时器
},
}
</script>
<style scoped>
</style>
然后我们引用一下
<template>
<div>
<module />
</div>
</template>
<script>
// 旋转展示数值组件
import module from './../../components/com24hourCountDown'
export default {
name: 'test',
components: {
module,
},
data() {
return {
}
},
methods: {
},
mounted() {
},
}
</script>
<style scope>
</style>
参考文章
评论抽奖
欢迎在评论区讨论,掘金官方将在掘力星计划活动结束后,在评论区抽送100份掘金周边
- 抽奖礼物:100份,掘金官方提供,包括掘金徽章、拖鞋、马克杯、帆布袋等,随机发放
- 抽奖时间:「掘力星计划」活动结束后,预计3个工作日内,官方将在所有符合规则的活动文章评论区抽出
- 抽奖方式:掘金官方随机抽奖+人工核实
- 评论内容:与文章内容相关的评论、建议、讨论等,「踩踩」「学习了」等泛泛类的评论无法获奖
都看到这里了,求各位观众大佬们点个赞再走吧,你的赞对我非常重要