Vue3搜索组件出现Maximum call stack size exceeded错误的解决方法
问题原因
search和filterByMetro函数互相调用形成无限递归:
- 当
metro.value.id存在且query.value不为空时,search会调用filterByMetro - 进入
filterByMetro后,因query.value不为空,又会反向调用search - 循环往复导致调用栈溢出,触发
Maximum call stack size exceeded错误
修改方案
重构过滤逻辑,将地铁筛选和关键词搜索合并为独立处理步骤,彻底避免递归调用:
<template> <div class="search"> <input type="text" @input="search($event.target.value.trim())" /> </div> </template> <script setup> const props = defineProps({ data: { type: Array, default: () => [] }, metro: { type: Object, default: () => {} } }) const emit = defineEmits(['onSearch']) const query = ref("") // 统一处理所有筛选逻辑:先地铁筛选,再关键词搜索 const applyFilters = () => { let filteredData = [...props.data] // 地铁筛选逻辑 if (props.metro.id) { filteredData = filteredData.filter(item => { return props.metro.metro === 1 ? item.district.id === props.metro.id : item.district.isMetro === false }) } // 关键词搜索逻辑 if (query.value !== '' && filteredData.length > 0) { const rx = new RegExp("^" + query.value, "im") const rxm = new RegExp('(?<= )[а-яА-Яa-zA-Z][а-яА-Яa-zA-Z ]*(?=,| )', 'giu') filteredData = filteredData.map(item => [ (rx.test(item.address.match(rxm)?.[0] || null) ? 1 : 0) || (rx.test(item.district.map(d => d.title).join("\n")) ? 2 : 0), item ]) .filter(([k]) => k) .sort((a, b) => a[0] - b[0]) .map(([_, v]) => v) } emit('onSearch', filteredData, query.value) return filteredData } const search = (val) => { query.value = val applyFilters() } // 监听地铁参数变化,自动触发筛选 watch(() => props.metro, () => { applyFilters() }, { deep: true }) </script>
修改说明
- 移除递归依赖:删除原函数互相调用的逻辑,用
applyFilters统一处理两个筛选条件 - 分层筛选:基于原始
props.data先做地铁筛选,再处理关键词搜索,避免循环依赖 - 简化状态管理:直接使用
props.metro,不再维护本地重复状态,减少同步问题 - 优化监听:添加
deep: true确保地铁对象内部属性变化时能触发筛选 - 边界处理:给props设置默认值,避免空数据导致的异常
内容的提问来源于stack exchange,提问作者Andreas Hunter
相关产品推荐
相关产品推荐

