Vue Computed引起的页面卡死
2024-10-28 15:48:32 2
前端出现了个bug
当请求接口时, 前端就会卡死, 直接无响应.
控制台看到对应请求的Timing一直卡在Initial connection.
将请求单独拿出来放到Postman中请求, 正常响应.
通过控制台Network中请求的Initialor进行断点跟踪, 发现前端实际也是获取到了接口的响应. 页面卡死多半是因为逻辑上死循环了.
启动开发环境进入页面调用, 发现Vue给了一个警告, 大致意思是触发了无限循环.
通过一个个删除元素定位到了引起问题的代码
是computed的两个函数
模拟复现代码如下
<template>
<button @click="get">GET</button>
<p v-bind:key="item.d" v-for="item in this.others">{{ item.d }}</p>
<div>{{ computed_a }}</div>
<div>{{ computed_b }}</div>
</div>
</template>
export default {
name: 'HelloWorld',
props: {
msg: String
},
data() {
return {
rmb_count: 0,
usd_count: 0,
others: []
};
},
computed: {
computed_a: function () {
this.rmb_count = this.others.reduce((title, item) => {
return title + item.d
}, 0);
this.usd_count = this.others.reduce((title, item) => {
return title + item.d
}, 0);
this.rmb_count = this.rmb_count + this.usd_count
this.usd_count = this.rmb_count + this.usd_count
return "new Date().getTime()" + this.rmb_count.toFixed(2) + " " + this.usd_count.toFixed(2)
},
computed_b: function () {
this.rmb_count = this.others.reduce((title, item) => {
return title + item.d
}, 0);
this.usd_count = this.others.reduce((title, item) => {
return title + item.d
}, 0);
this.rmb_count = this.rmb_count + this.usd_count
this.usd_count = this.rmb_count + this.usd_count
return "new Date().getTime()" + this.rmb_count.toFixed(2) + " " + this.usd_count.toFixed(2)
}
},
methods: {
get() {
this.others = [{d: 1.1}, {d: 2.1}, {d: 3.1}, {d: 4.1}]
}
}
}
当请求接口更新others
时, 触发了computed a/b
然后在computed
内, rmb_count/usd_count
被更新
因为computed
将rmb_count/usd_count
识别为了依赖项, 所以computed a/b
继续被触发, 就这样死循环了
解决方法
将rmb_count/usd_count
用方法内的变量代替
vue:2.6.12