0%

Vue+Axios自动更新

本篇文章记录了作者在使用Vue+Axios实现前端自动刷新数据时,遇到的一个坑点。

场景需求

在一个Vue单页应用中,使用VueRouter实现了App组件中点击链接后呈现Component组件的功能

App.Vue -> Component.Vue

现在需要:在Component加载出来之后,每间隔1s的时间,自动通过Axios向后端接口获取数据并更新。

有问题的实现方式

App.Vue,内置router-link,可以跳转呈现Component

1
2
3
4
5
6
7
// App.Vue
<template>
<div>
<router-link :to="/Component">Component</router-link>
<router-view></router-view>
</div>
</template>

Component.Vue,在创建时,使用setInterval创建1s中的循环动作,在动作中使用Axios获取后端数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Component.Vue
<template>
<div></div>
</template>

<script>
export default {
created() {
// 设置一个间隔1s就进行的动作
setInterval(() => {
Axios.get("/data").then((res) => {
// 业务逻辑
})
}, 1000)
}
}
</script>

问题分析

出现问题的原因在于:

只有setInterval,没有clearInterval

一个循环任务一旦被创建,就没有被销毁的可能,但是每次用户点击Component链接,都会创建Component实例,产生循环任务。

如果用户多次点击了App.Vue中的Component链接,那么就会在前端浏览器里产生多个循环任务,不断发送请求,最终导致前后端都不堪重负。

解决方案

通过data记录created中产生的循环任务,并在beforeDestroy里加入clearInterval清除它。

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
// Component.Vue
<template>
<div></div>
</template>

<script>
export default {
data() {
return {
timer : {},
}
},
created() {
// 设置一个间隔1s就进行的动作
this.timer = setInterval(() => {
Axios.get("/data").then((res) => {
// 业务逻辑
})
}, 1000)
},
beforeDestroy() {
clearInterval(this.timer)
}
}
</script>