使用Vue实现倒计时是常见的需求,但是当页面进行刷新时,原有的倒计时会被重新开始,经常导致用户的混乱和不满。为了解决这个问题,我们可以使用JSON对象存储倒计时的剩余时长,在页面刷新时从JSON对象中读取信息,从而实现刷新界面不影响倒计时的效果。
具体实现步骤如下:
1. 利用Vue的生命周期函数
在Vue中,有一些生命周期函数可以用来监听组件的状态变化,我们可以通过这些函数来实现倒计时功能。
首先,我们在Vue组件创建时使用created
生命周期函数来初始化倒计时:
created: function() {
if(localStorage.countdown) {
this.countdown = JSON.parse(localStorage.countdown)
} else {
this.countdown = {
// 默认倒计时为30秒
seconds: 30,
timer: null
}
}
}
上述代码首先判断本地存储(localStorage
)中是否存储有计时器信息,如果有则从本地存储中读取,否则初始化一个默认的倒计时时间为30秒的计时器。通过这个全局变量,我们可以避免刷新页面时重置计时器。
接下来,我们还需要在Vue组件销毁时使用destroyed
生命周期函数清除localStorage
中存储的计时器信息:
destroyed: function() {
if(this.countdown.timer) {
clearInterval(this.countdown.timer)
}
localStorage.removeItem('countdown')
}
上述代码会停止计时器并清除本地存储。
2. 在模板中利用Vue的计算属性和方法
接下来,在Vue的模板中,我们可以利用Vue提供的计算属性和方法来渲染倒计时时间,并对倒计时进行控制。
首先,我们可以创建一个计算属性来计算剩余的倒计时秒数:
computed: {
count: function() {
var s = Math.max(0, this.countdown.seconds - this.passedSeconds)
if(this.countdown.timer) {
localStorage.countdown = JSON.stringify(this.countdown)
}
if(s === 0) {
clearInterval(this.countdown.timer)
}
return s
}
}
这个计算属性会根据当前时间和计时器的状态来计算剩余的计时秒数,如果倒计时时间为0,则清除计时器。
接下来,我们可以创建一个处理倒计时时间的方法:
methods: {
padNumber: function(num) {
return num < 10 ? `0${num}` : num
},
formatTime: function(seconds) {
var min = Math.floor(seconds / 60)
var sec = seconds % 60
return `${this.padNumber(min)}:${this.padNumber(sec)}`
},
startCountdown: function() {
if(this.countdown.timer) {
clearInterval(this.countdown.timer)
}
this.passedSeconds = 0
this.countdown.timer = setInterval(() => {
this.passedSeconds += 1
}, 1000)
}
}
在这个方法中,我们定义了三个子方法:padNumber
用于补充数字前导的0,formatTime
用于将时间格式化为“分:秒”的形式,startCountdown
用于开始倒计时。在startCountdown
方法中,我们清除之前的计时器(如果有),然后初始化已经过去的时间(即passedSeconds
),随后创建一个新的计时器来计算已经过去的时间。注意,在这里,我们没有直接对倒计时时间进行操作,而是利用了标准计时器的形式来操作已经过去的时间,这是为了避免页面刷新后的初始延迟问题。
示例
下面是一个基于Vue实现的倒计时计时器的简单示例:
<template>
<div>
<p>{{ formatTime(count) }}</p>
<button @click="startCountdown">Start</button>
</div>
</template>
<script>
export default {
name: 'Countdown',
data() {
return {
countdown: null,
passedSeconds: 0
}
},
created: function() {
if(localStorage.countdown) {
this.countdown = JSON.parse(localStorage.countdown)
} else {
this.countdown = {
seconds: 30,
timer: null
}
}
},
destroyed: function() {
if(this.countdown.timer) {
clearInterval(this.countdown.timer)
}
localStorage.removeItem('countdown')
},
computed: {
count: function() {
var s = Math.max(0, this.countdown.seconds - this.passedSeconds)
if(this.countdown.timer) {
localStorage.countdown = JSON.stringify(this.countdown)
}
if(s === 0) {
clearInterval(this.countdown.timer)
}
return s
}
},
methods: {
padNumber: function(num) {
return num < 10 ? `0${num}` : num
},
formatTime: function(seconds) {
var min = Math.floor(seconds / 60)
var sec = seconds % 60
return `${this.padNumber(min)}:${this.padNumber(sec)}`
},
startCountdown: function() {
if(this.countdown.timer) {
clearInterval(this.countdown.timer)
}
this.passedSeconds = 0
this.countdown.timer = setInterval(() => {
this.passedSeconds += 1
}, 1000)
}
}
}
</script>
在这个示例中,我们在Vue的计算属性中计算了剩余的倒计时秒数,利用Vue的方法来渲染倒计时时间,并创建了一个简单的“Start”按钮来开始倒计时。如果你复制这个代码到你的Vue项目中,就可以完整地体验倒计时的效果了。
示例二:倒计时列表
下面提供另外一个实例,这个示例展示了如何在一个列表中实现多个倒计时计时器:
<template>
<div>
<ul>
<li v-for="item in list" :key="item.id">
<p>{{ formatTime(item.count) }}</p>
<button @click="startCountdown(item)">Start</button>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'CountdownList',
data() {
return {
list: []
}
},
created: function() {
if(localStorage.countdownList) {
this.list = JSON.parse(localStorage.countdownList)
} else {
this.list = [
{ id: 1, seconds: 30, timer: null, passedSeconds: 0 },
{ id: 2, seconds: 90, timer: null, passedSeconds: 0 }
]
}
},
destroyed: function() {
this.list.forEach(item => {
if(item.timer) {
clearInterval(item.timer)
}
})
localStorage.removeItem('countdownList')
},
computed: {
},
methods: {
padNumber: function(num) {
return num < 10 ? `0${num}` : num
},
formatTime: function(seconds) {
var min = Math.floor(seconds / 60)
var sec = seconds % 60
return `${this.padNumber(min)}:${this.padNumber(sec)}`
},
startCountdown: function(item) {
if(item.timer) {
clearInterval(item.timer)
}
item.passedSeconds = 0
item.timer = setInterval(() => {
item.passedSeconds += 1
if(item.count <= item.passedSeconds) {
clearInterval(item.timer)
}
}, 1000)
this.saveCountdownList()
},
saveCountdownList: function() {
localStorage.countdownList = JSON.stringify(this.list)
}
}
}
</script>
在这个示例中,我们创建了一个倒计时计时器列表,它包含了数量和时长不同的两个计时器。我们使用v-for
指令和Vue的计算属性来动态地渲染列表。当用户点击“Start”按钮时,调用startCountdown
方法来启动相应的倒计时计时器,当计时器到达结束时间时,清除计时器。同时,我们将倒计时列表保存到本地存储,以使页面刷新后仍然保持原有的倒计时状态。
这两个示例提供了如何使用Vue和JSON对象在刷新页面时不影响倒计时功能的方法。通过加深Vue框架的理解,并使用合适的方法和技术,我们可以使我们的网站更加出色和用户友好。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Vue中用JSON实现刷新界面不影响倒计时 - Python技术站