vue项目运行时,报了下面的错误:
Uncaught (in promise) Maximum recursive updates exceeded. This means you have a reactive effect that is mutating its own dependencies and thus recursively triggering itself. Possible sources include component template, render function, updated hook or watcher source function
原代码
<template>
<div class="itemBodys hideScrollBar">
<Vue3SeamlessScroll :step="0.5" :wheel="true" :hover="true" :list="sortList" class="tableBody">
<div class="list">
<div class="listItem" v-for="(item,index) in sortList" :key="index">
<div class="listItemTop">
<div class="icon" :style="getIconBackground(index)">
{{ index + 1 }}
</div>
<span class="name">{{ item.name }}</span>
</div>
<div class="listItemBottom">
<progressBar :index="index" :total="total" :item="item"></progressBar>
</div>
</div>
</div>
</Vue3SeamlessScroll>
</div>
</template>
<script>
import progressBar from './components/progressBar.vue'
import ranking4 from './components/assets/ranking4.png'
import ranking1 from './components/assets/ranking1.png'
import ranking2 from './components/assets/ranking2.png'
import ranking3 from './components/assets/ranking3.png'
import {Vue3SeamlessScroll} from "vue3-seamless-scroll";
export default {
name: "title",
data() {
return {
list: []
}
},
components: {progressBar,Vue3SeamlessScroll},
props: {
// 类型 0所有数据累加作为基数进行占比计算 1取数据中最大的数值作为基数进行计算
type: {
type: Number,
default() {
return 1;
}
},
},
computed: {
sortList: function () {
return this.sortKey(this.list, 'value')
},
total: function () {
var total = 0
if (this.type == 0) {
total = this.getTotalByKey(this.list, 'value')
} else {
total = this.getMaxNumByKey(this.list, 'value')
}
return total
},
},
mounted() {
this.getData()
},
methods: {
getIconBackground(index) {
let imageUrl = ranking4; // 默认图片
if (index === 0) {
imageUrl = ranking1;
} else if (index === 1) {
imageUrl = ranking2;
} else if (index === 2) {
imageUrl = ranking3;
}
return `background: url(${imageUrl}) no-repeat; background-size: 100% 100%;`;
},
async getData() {
function generateRandomArray() {
const names = [
"计算机科学与技术",
"人工智能",
"供应链管理",
"历史学",
"理学",
"工程学",
"文学",
"教育学",
"经济学",
"艺术",
"公共健康",
"商学"
];
const result = names.map(name => {
return {
name: name,
value: Math.floor(Math.random() * (200 - 100 + 1)) + 100
};
});
return result;
}
this.list = generateRandomArray();
},
sortKey(array, key) {
var list = array.sort(function (a, b) {
var x = a[key];
var y = b[key];
return ((x < y) ? -1 : (x > y) ? 1 : 0)
})
return list.reverse()
},
getMaxNumByKey(list, key) {
var maxNum = list[0][key];
list.forEach((type) => {
if (type[key] > maxNum) {
maxNum = type[key]
}
});
return maxNum
},
getTotalByKey(list, key) {
var total = 0;
list.forEach((type) => {
total = total + type[key]
});
return total
},
},
}
</script>
你遇到的错误 Maximum recursive updates exceeded
表明在你的 Vue.js 组件中存在一个无限递归更新的问题。这个问题通常是由于某个响应式数据的变化触发了自身的更新,从而导致无限循环。
在你的代码中,可能的原因包括以下几个方面:
-
sortList
计算属性:sortList
是一个计算属性,它依赖于this.list
。如果this.list
的变化会触发sortList
的重新计算,而sortList
的重新计算又会触发this.list
的变化,就会导致无限循环。 -
total
计算属性:total
计算属性依赖于this.list
和this.type
。如果this.list
或this.type
的变化会触发total
的重新计算,而total
的重新计算又会触发this.list
或this.type
的变化,也会导致无限循环。
解决方法
-
检查计算属性的依赖关系:确保计算属性的依赖关系不会导致无限循环。
-
避免在计算属性中直接修改依赖数据:计算属性应该是纯粹的计算,不应该直接修改依赖的数据。
-
使用
watch
监听数据变化:如果需要在数据变化时执行某些操作,可以使用watch
而不是计算属性。
示例修改
以下是一些可能的修改建议:
- 确保
sortList
和total
计算属性不会直接修改this.list
:
computed: {
sortList() {
return this.sortKey([...this.list], 'value'); // 使用拷贝的数组进行排序
},
total() {
if (this.type === 0) {
return this.getTotalByKey(this.list, 'value');
} else {
return this.getMaxNumByKey(this.list, 'value');
}
}
}
- 检查
sortKey
方法:确保sortKey
方法不会直接修改this.list
:
methods: {
sortKey(array, key) {
return array.slice().sort((a, b) => b[key] - a[key]); // 使用拷贝的数组进行排序
},
// 其他方法保持不变
}
- 使用
watch
监听list
的变化:
watch: {
list(newList) {
// 在这里执行需要的操作,而不是在计算属性中
}
}
完整代码示例
<template>
<div class="itemBodys hideScrollBar">
<Vue3SeamlessScroll :step="0.5" :wheel="true" :hover="true" :list="sortList" class="tableBody">
<div class="list">
<div class="listItem" v-for="(item, index) in sortList" :key="index">
<div class="listItemTop">
<div class="icon" :style="getIconBackground(index)">
{{ index + 1 }}
</div>
<span class="name">{{ item.name }}</span>
</div>
<div class="listItemBottom">
<progressBar :index="index" :total="total" :item="item"></progressBar>
</div>
</div>
</div>
</Vue3SeamlessScroll>
</div>
</template>
<script>
import progressBar from './components/progressBar.vue'
import ranking4 from './components/assets/ranking4.png'
import ranking1 from './components/assets/ranking1.png'
import ranking2 from './components/assets/ranking2.png'
import ranking3 from './components/assets/ranking3.png'
import { Vue3SeamlessScroll } from "vue3-seamless-scroll";
export default {
name: "item6",
data() {
return {
list: []
}
},
components: { progressBar, Vue3SeamlessScroll },
props: {
type: {
type: Number,
default() {
return 1;
}
},
},
computed: {
sortList() {
return this.sortKey([...this.list], 'value'); // 使用拷贝的数组进行排序
},
total() {
if (this.type === 0) {
return this.getTotalByKey(this.list, 'value');
} else {
return this.getMaxNumByKey(this.list, 'value');
}
}
},
mounted() {
this.getData();
},
methods: {
getIconBackground(index) {
let imageUrl = ranking4; // 默认图片
if (index === 0) {
imageUrl = ranking1;
} else if (index === 1) {
imageUrl = ranking2;
} else if (index === 2) {
imageUrl = ranking3;
}
return `background: url(${imageUrl}) no-repeat; background-size: 100% 100%;`;
},
async getData() {
function generateRandomArray() {
const names = [
"计算机科学与技术",
"人工智能",
"供应链管理",
"历史学",
"理学",
"工程学",
"文学",
"教育学",
"经济学",
"艺术",
"公共健康",
"商学"
];
return names.map(name => ({
name: name,
value: Math.floor(Math.random() * (200 - 100 + 1)) + 100
}));
}
this.list = generateRandomArray();
},
sortKey(array, key) {
return array.slice().sort((a, b) => b[key] - a[key]); // 使用拷贝的数组进行排序
},
getMaxNumByKey(list, key) {
return Math.max(...list.map(item => item[key]));
},
getTotalByKey(list, key) {
return list.reduce((total, item) => total + item[key], 0);
}
}
}
</script>
通过这些修改,可以避免无限递归更新的问题。如果问题仍然存在,请进一步检查代码中的其他部分,确保没有其他地方导致无限循环。