子组件递归使用不当,导致的错误
浏览器console报警
chunk-ZMYV2364.js?v=527d878f:1381 [Vue warn]: Extraneous non-props attributes (menus) were passed to component but could not be automatically inherited because component renders fragment or text root nodes.
浏览器console错误
Maximum call stack size exceeded
向ChatGPT提问
我用vue3+typescript+pinia技术开发项目时碰到个问题,以下是浏览器控制台的提示信息:
[Vue warn]: Extraneous non-props attributes (menus) were passed to component but could not be automatically inherited because component renders fragment or text root nodes
ChatGPT回答
这个警告信息是Vue的一个常见警告信息之一,意思是在组件中传递了一些非props属性,但这些属性无法被组件自动继承,因为组件渲染了片段或文本根节点。
这个问题通常是由于在组件标签中传递了一些非props属性,而组件并没有显式声明这些属性,导致Vue无法识别它们并将其传递给组件。解决方法是将这些非props属性从组件标签中删除,或者将它们作为props属性声明到组件中。
对于您的情况,您可以检查组件标签中是否有一个名为"menus"的属性,如果是,您可以将其删除或者将其作为一个props属性声明到组件中。具体的实现方式取决于您的具体情况,您可以参考Vue文档中关于组件属性的说明。
解决方案
当调用的子组件递归使用自己时,使用defineProps的方式代替pinia store的共享数据
因为递归调用自己,所以必须要用defineProps传值
父组件代码
import { roleStore } from '@/pinia/roleStore'
// 使用pinia定义的store
const useRoleStore = roleStore()
// 加载所有角色的数据
useRoleStore.findRoles()
<el-menu @select="useRoleStore.handleSelectMenu">
<!-- 调用子组件:传递角色数据,定义函数接收子组件的值 -->
<!-- 虽然可以pinia共享数据,但这个子组件递归调用了自己,所以还是需要传值 -->
<menu-item :menus="useRoleStore.rolesData" />
</el-menu>
子组件代码
<!-- 左侧菜单 -->
<script setup lang='ts'>
defineProps(['menus'])
</script>
<template>
<!-- 注意:有两层template,第一层是必须的,第二层是为了遍历数据 -->
<template v-for="(menu, index) in menus" :key="index">
<!-- v-if判断:是否有children,有就递归 -->
<el-sub-menu v-if="menu.children" :index="menu.name">
<!-- 注意:要用template包裹标题,并且绑定title -->
<template #title>
<el-icon><Menu /></el-icon>
<span class="menu-title">{{ menu.name }}</span>
</template>
<!-- 递归使用组件:MenuItem.vue -->
<menu-item :menus="menu.children"></menu-item>
</el-sub-menu>
<el-menu-item v-else :index="menu.name">
<el-icon><Avatar /></el-icon>
<span>{{ menu.name }}</span>
</el-menu-item>
</template>
</template>
<style lang='scss' scoped>
.menu-title{
// color: $dark-blue;
font-weight: bold;
}
</style>