@@ -12,7 +12,6 @@ import styles from './index.module.less'
1212
1313import { mainLayoutMenu } from '@src/config/menu.config'
1414
15- // Defer lazyComponents import to avoid layout/lazyLoad circular reference during module evaluation
1615let lazyComponentsCache = null
1716let lazyComponentsPromise = null
1817const loadLazyComponents = ( ) => {
@@ -157,7 +156,10 @@ const ProSecNav = ({ mode = 'inline', theme = 'light', onMenuClick }) => {
157156 }
158157
159158 const dfs = ( nodes , chain ) => {
159+ if ( ! Array . isArray ( nodes ) ) return
160160 for ( const node of nodes ) {
161+ // 添加空值检查
162+ if ( ! node || typeof node !== 'object' || ! node . key ) continue
161163 const nextChain = [ ...chain , node . key ]
162164 const nodePath = node . path || node . key
163165 // 匹配规则:精确匹配 或 前缀匹配(允许 /a/b 命中 /a)
@@ -171,7 +173,9 @@ const ProSecNav = ({ mode = 'inline', theme = 'light', onMenuClick }) => {
171173 bestChain = nextChain
172174 }
173175 }
174- if ( node . children ) dfs ( node . children , nextChain )
176+ if ( node . children && Array . isArray ( node . children ) ) {
177+ dfs ( node . children , nextChain )
178+ }
175179 }
176180 }
177181 dfs ( items , [ ] )
@@ -224,9 +228,16 @@ const ProSecNav = ({ mode = 'inline', theme = 'light', onMenuClick }) => {
224228 // 计算所有当前 key 的父链深度(根据 menuItems)
225229 const depthMap = { }
226230 const buildDepth = ( items , depth ) => {
231+ if ( ! Array . isArray ( items ) ) return
227232 for ( const item of items ) {
228- depthMap [ item . key ] = depth
229- if ( item . children ) buildDepth ( item . children , depth + 1 )
233+ // 添加空值检查,避免 "Cannot convert undefined or null to object" 错误
234+ if ( ! item || typeof item !== 'object' ) continue
235+ if ( item . key ) {
236+ depthMap [ item . key ] = depth
237+ }
238+ if ( item . children && Array . isArray ( item . children ) ) {
239+ buildDepth ( item . children , depth + 1 )
240+ }
230241 }
231242 }
232243 buildDepth ( menuItems , 0 )
@@ -297,8 +308,15 @@ const ProSecNav = ({ mode = 'inline', theme = 'light', onMenuClick }) => {
297308 }
298309
299310 const translateItem = ( i ) => {
311+ // 添加空值检查
312+ if ( ! i || typeof i !== 'object' ) return null
313+
300314 const { i18nKey, children, ...rest } = i
301315 const path = i . path || i . key
316+
317+ // 如果没有 key,返回 null(不合法的菜单项)
318+ if ( ! path ) return null
319+
302320 const labelText = i18nKey ? t ( i . i18nKey ) : i . label
303321 const Label = createLabel ( path , labelText )
304322
@@ -307,11 +325,17 @@ const ProSecNav = ({ mode = 'inline', theme = 'light', onMenuClick }) => {
307325 path,
308326 label : Label ,
309327 }
310- return children ? { ...base , children : children . map ( translateItem ) } : base
328+ if ( children && Array . isArray ( children ) ) {
329+ // 过滤掉空值的子项
330+ const validChildren = children . map ( translateItem ) . filter ( Boolean )
331+ return validChildren . length > 0 ? { ...base , children : validChildren } : base
332+ }
333+ return base
311334 }
312335
313336 // 使用配置文件的菜单,并进行翻译;同时规范化每项的 path 字段
314- const allMenuItems = mainLayoutMenu . map ( translateItem )
337+ // 过滤掉可能的空值
338+ const allMenuItems = ( Array . isArray ( mainLayoutMenu ) ? mainLayoutMenu : [ ] ) . map ( translateItem ) . filter ( Boolean )
315339
316340 // 递归过滤菜单:仅保留用户可访问的节点或其子节点
317341 const hasAccessSafely = ( p ) => {
@@ -331,9 +355,15 @@ const ProSecNav = ({ mode = 'inline', theme = 'light', onMenuClick }) => {
331355 }
332356
333357 const filterItems = ( items ) => {
358+ if ( ! Array . isArray ( items ) ) return [ ]
334359 const result = [ ]
335360 for ( const item of items ) {
361+ // 添加空值检查,防止处理空值菜单项
362+ if ( ! item || typeof item !== 'object' ) continue
363+
336364 const rawKey = item . path || item . key
365+ // 如果菜单项没有 key,跳过(不合法的菜单项)
366+ if ( ! rawKey ) continue
337367
338368 if ( Array . isArray ( item . children ) && item . children . length > 0 ) {
339369 const children = filterItems ( item . children )
0 commit comments