赞
踩
在做一个项目的过程中,需要对后端返回的数据做
sort()
排序处理,然后使用v-for指令渲染页面数据;视图虽然渲染出来了,但是控制台报错如下:You may have an infinite update loop in a component render function(意思是:组件渲染函数中可能有一个无限更新循环)
<div class="list"> <ul v-for="(item, index) in sortList(copyTextList)" :key="index"> <li class="item">{{ index + 1 }}:{{ item.text }}</li> </ul> </div> export default { data() { return { // 多行文本进行复制 copyTextList: [], }; }, mounted() { this.initList(); }, methods: { // 请求数据 async initList() { const { isSuccess, data, code } = await api.requestList.queryCopyList(); if (isSuccess) { this.copyTextList = data; } }, // 排序操作 sortList(list) { let sortList = list.sort((a, b) => { return a.num - b.num; }); return sortList; } }
运行效果图如下:
如上代码所示:先在mounted里面请求数据,然后赋值给data里面的copyTextList
数组,v-for的时候再对数组进行排序操作;
问题产生的原因
:你在data中定义了一个响应式变量,而这个响应式变量的状态是通过一个函数来返回的,返回的状态结果要显示在Dom中,而这个函数的内部是一个循环;
问题来了
:循环没有及时终止,导致变量一直在更新,而Dom又一直在渲染,无限循环,渲染-更新 卡死;
第一种:
具体问题不一样,但都是死循环类型,所以处理方式也是差不多的。就是不直接对响应式数据进行操作,对响应式数据的副本进行排序然后并返回计算结果;
下面是尤玉溪
在github上面给出的解决方案;先使用一个空的slice方法,然后在使用sort排序方法;
不能直接使用sort方法;因为sort方法会改变原数组,从而导致多次渲染;
而数组的slice() 方法返回一个新的数组对象,这一对象是一个由 begin 和 end 决定的原数组的浅拷贝(包括 begin,不包括end)。原始数组不会被改变。
所以
上面我的错误代码可以改为:
// 排序操作
sortList(list) {
let sortList = list.slice().sort((a, b) => {
return a.num - b.num;
});
return sortList;
}
第二种:
与上面的思路相同;深拷贝一下原数组然后再进行排序:
// 排序操作
sortList(list) {
let sortList =JSON.parse(JSON.stringify(list)).sort((a, b) => {
return a.num - b.num;
});
return sortList;
},
第三种:
这一种方法也能解决问题,但是比较麻烦一点:不推荐使用
其实出现报错的根源就在于把数组定义到了 vue实例的data里面,因为vue初始化时会把data里面的所有数据都添加响应式依赖;会监听数组的变化然后做出一些渲染;那我把数据不定义到vue实例里面不就可以了吗;看以下代码改动:
我把
copyTextList
定义到了最上面;然后对他赋值然后直接进行sort排序;排完之后再次赋值给一个data里面的newList
让它进行渲染视图;
<template> <div class="list"> <ul v-for="(item, index) in newList" :key="index"> <li class="item">{{ index + 1 }}:{{ item.text }}</li> </ul> </div> </template> <script> import api from '../../api'; // 把数据定义到了外面 let copyTextList = []; export default { data() { return { newList: [], }; }, mounted() { this.initList(); }, methods: { // 请求数据 async initList() { const { isSuccess, data, code } = await api.requestList.queryCopyList(); if (isSuccess) { copyTextList = data; this.sortList(copyTextList); } }, // 排序操作 sortList(list) { this.newList = list.sort((a, b) => { return a.num - b.num; }); }, }, };
End;
如果你们有其他的解决方案;可以写到评论区下面;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。