vue使用sort排序时报死循环错误:you may have an infinite update loop in a component render function

问题产生的原因:你在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;
      });
    },
  },
};