赞
踩
问题产生的原因
:你在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;
});
},
},
};
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。