在前端开发学习中,用JavaScript脚本写个数字时钟是很常见的案例,也没什么难度。今天有时间,于是就用Vue的方式来实现这个功能。原本以为是件非常容易的事,没想到却卡在两个问题上,一个问题通过别人的博文已经找到答案,还有一个问题却还是不知道是什么原因造成的。
问题一 this指向的问题
mounted() {
var _this = this;
setInterval(function () {
_this.today = new Date()
}, 1000)
}
在上面这段代码中,我开始不太理解为什么要把 _this = this,感觉有点多此一举。于是便把这行代码弃了,直接用this,结果程序不能正常执行了。我知道是this的原因,但是个中具体的缘由却说不明白。
后来在网上看到一篇博文,把这个问题三言两语就说明白了,非常感谢博主的分享。
我们要获取vue变量或方法的时候,一般使用this,但是在回调函数中,this指向的就不是vue变量,而是回调函数本身,所以在一开始的时候,先定义_this=this,这样在任何位置都可以用_this来获取vue变量或方法。
也就是说,回调函数外的this指的是Vue对象,回调函数内的this默认是指向回调函数了,两者不相同,这样_this = this就不难理解了。
问题2 格式化时、分、秒的时候,用了三目运算符,分成两行写,程序可以正常运行,合成一行写就是undefined。
(1)分成两行写,正常运行,代码如下,效果如图。
var second = this.today.getSeconds()
second = second < 10 ? '0' + second : second
(2)合成一行写,显示undefined,代码如下,效果如下图,加上括号运行也是undefined
var second = this.today.getSeconds() < 10 ? '0' + second : second
var second = (this.today.getSeconds() < 10 )? '0' + second : second
试了一下,在javaScript中也是这样的,我不清楚是什么原因造成的,是我的代码有错误吗?或者三目运算符有什么要求?
完整代码如下:
<!DOCTYPE html>
<html>
<head>
<title>实时显示的日期和时间</title>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
</head>
<body>
<div id="app">
{{message}}
<sub-component v-if="show"></sub-component>
<button @click="change">切换</button>
</div>
<template id="displayTime">
<div>
{{dispTime() }}
</div>
</template>
</body>
<script type="text/javascript">
const SubComponent = {
template:'#displayTime',
data() {
return {
today: new Date(),
}
},
methods: {
dispTime() {
var year = this.today.getFullYear()
var month = this.today.getMonth() + 1
var date = this.today.getDate()
var hour = this.today.getHours()
hour = hour < 10 ? '0' + hour : hour
var minute = this.today.getMinutes();
minute = minute < 10 ? '0' + minute : minute
// var second = this.today.getSeconds()
// second = second < 10 ? '0' + second : second
var second = this.today.getSeconds() < 10 ? '0' + second : second
return `${year}年${month}月${date}日${hour}:${minute}:${second}`
}
},
mounted() {
var _this = this;
var timer = setInterval(function () {
_this.today = new Date()
}, 1000)
},
//实例销毁之前调用
beforeUnmount() {
if (this.timer) {
clearInterval(this.timer); //在Vue实例销毁前清除定时器
}
console.log('清除时钟')
}
}
const RootComponent={
data() {
return {
message: '数字时钟',
show: true,
}
},
methods: {
change() {
this.show = !this.show
}
},
components:{
SubComponent,
}
}
const vueApp = Vue.createApp(RootComponent)
vueApp.mount("#app")
</script>
</html>