当前位置: 首页 > 知识库问答 >
问题:

javascript - vue3 computed中的代码导致栈溢出?

荀子轩
2024-05-27
// index.vue<custom-calendar :check-date="checkDate" class="calendar-box" />// CustomCalenda.vaue<script lang="ts" setup>const props = defineProps({  checkDate: {    type: Array,    default() {      return []    }  }})const minDate = computed(() => {  debugger  if (props.checkDate.length) {    let newArr = props.checkDate.sort((a:any, b:any):number => a.getTime() - b.getTime())    return new Date(+newArr[0] as number)  } else {    return new Date()  }})const maxDate = computed(() => {  debugger  if (props.checkDate.length) {    let newArr = props.checkDate.sort((a:any, b:any):number => b.getTime() - a.getTime())     return new Date(+newArr[0] as number)  } else {    return new Date()  }})const curYear = ref<number>(new Date().getFullYear())const curMonth = ref<number>(new Date().getMonth())watch(() => maxDate.value, (newVal:Date|null) => {  debugger  if (newVal) {    curYear.value = newVal.getFullYear()    curMonth.value = newVal.getMonth()  }}, {  immediate: true})

这段代码控制台报栈溢出
image.png
我打了断点,发现代码会在两个computed中无限的执行下去,导致栈溢出,但是我没有找到原因为什么会循环执行?

共有2个答案

小牛23038
2024-05-27

简单解决方法:
props.checkDate 排序前先 slice 一下

const minDate = computed(() => {  if (props.checkDate.length) {    let newArr = props.checkDate.slice().sort((a, b) => a.getTime() - b.getTime())    console.log('newArr', JSON.stringify(newArr))    return new Date(+newArr[0])  } else {    return new Date()  }})const maxDate = computed(() => {  if (props.checkDate.length) {    let newArr = props.checkDate.slice().sort((a, b) => b.getTime() - a.getTime())     console.log('newArr', JSON.stringify(newArr))    return new Date(+newArr[0])  } else {    return new Date()  }})

在线查看:
https://play.vuejs.org/#eNrlVk1P20AQ/SsjX+JQYxe1VQEFJNpSqUgFV...

稍后有时间,我详细说明一下原因

丌官信厚
2024-05-27

在Vue中,使用computed属性时,如果依赖的响应式属性发生变化,computed属性会自动重新计算。在你提供的代码中,minDatemaxDate两个computed属性都依赖于props.checkDate数组。如果checkDate数组发生变化,这两个属性都会重新计算,而每个computed属性的计算过程中又都会对checkDate数组进行排序操作,这可能导致它们相互触发重新计算,从而形成无限循环。

可以如下面这样修改看看:

<script lang="ts" setup>import { ref, computed, watch, onMounted } from 'vue';const props = defineProps({  checkDate: {    type: Array,    default() {      return []    }  }});// 新增一个响应式属性来存储排序后的数组const sortedCheckDates = ref([]);const minDate = computed(() => {  if (sortedCheckDates.value.length) {    return new Date(sortedCheckDates.value[0].getTime());  } else {    return new Date();  }});const maxDate = computed(() => {  if (sortedCheckDates.value.length) {    return new Date(sortedCheckDates.value[sortedCheckDates.value.length - 1].getTime());  } else {    return new Date();  }});// 监听checkDate的变化,并更新sortedCheckDateswatch(() => props.checkDate, (newVal) => {  sortedCheckDates.value = newVal.sort((a, b) => a.getTime() - b.getTime());});const curYear = ref(new Date().getFullYear());const curMonth = ref(new Date().getMonth());watch(() => maxDate.value, (newVal) => {  if (newVal) {    curYear.value = newVal.getFullYear();    curMonth.value = newVal.getMonth();  }}, {  immediate: true});onMounted(() => {  // 初始化sortedCheckDates  sortedCheckDates.value = props.checkDate.sort((a, b) => a.getTime() - b.getTime());});</script>
 类似资料:
  • 问题内容: 这有效:http : //play.golang.org/p/-Kv3xAguDR。 这导致堆栈溢出:http : //play.golang.org/p/1-AsHFj51O。 我不明白为什么。在这种情况下,使用接口的正确方法是什么? 问题答案: 这个 将呼叫您的,依次呼叫,等等。如果您需要解组JSON然后对其进行处理,那么一种巧妙的技术是声明一个本地类型,将数据解组到其中,然后转换

  • 我正在使用一个正则表达式从任意长的输入字符串中提取键值对,并且遇到了这样的情况:对于具有重复模式的长字符串,它会导致堆栈溢出。 KV解析代码如下所示: 一些虚构的输出示例: 我显式地将generic放在上面,而不是在解析之前检查最大字符串长度的hacks(例如)。 我能想出的最粗俗的解决方法,一个真正的反模式,是 有趣的是,它在我试过的几次运行中都起作用了,但它不是一个值得推荐的有品位的东西。:-

  • 我找不到堆栈溢出的来源,但似乎是外部的循环造成的。 提前道谢!

  • 问题内容: TL; DR: 将任何非内置函数添加到Array.prototype AND Function.prototype将导致IE8本机JSON解析器在解析包含数组的任何JSON时发生堆栈溢出,但仅当您还传递了reviver函数时放入JSON.parse()。 最初这是一个问题,但我回答了我自己的原始问题,所以现在我要问:有人能想到此IE8错误的解决方法,该方法不涉及消除所有修改Array.

  • 我有一个名为User的实体,它有一组角色。我还有一个角色实体,它有一组用户。(这只是出于学习目的的实践应用。) 问题是——我有一个UserController(REST API)来发送用户列表——这会导致StackOverFlow错误。用户试图加载角色,而角色又试图加载用户等。 我的问题是——如何避免这种情况?我也看到许多类似的设计。例如:https://viralpatel.net/blogs/

  • 我正在研究这个简单的问题来练习基本Kotlin,在递归返回行上遇到了堆栈溢出,代码如下: 我对tailrec的理解是,它应该将递归函数转换为迭代函数,而迭代函数不会受到这种崩溃的影响。如果我没有正确实现尾部递归,编译器应该会发出错误。 有人能解释一下为什么这会像标准递归调用一样在大输入上崩溃吗?