vueComponent / pro-components

easy use `Ant Design Vue` layout
MIT License
540 stars 215 forks source link

[BUG] layout 菜单错误 #266

Open luocong2016 opened 1 year ago

luocong2016 commented 1 year ago

🐛 Bug 描述 Bug description

  1. 非 '/'开始的 path 名字相同,被认为是激活了同个路由
    path: "index"

    image

看了下源码

// packages/pro-layout/src/components/SiderMenu/BaseMenu.tsx
// 这里 memu key 使用的是 path
  1. getMenuData, clearMenuItem typescript 类型兼容eslint报错, 只能加 any; 源码拷贝到本地是不报错的

    const { menuData } = getMenuData(clearMenuItem(router.getRoutes() as any));
  2. clearMenuItem 关于 name 强制绑定这个明显在 vue 中是有问题的

    // 代码使用了 to -> name 来跳转
  3. getMenuData 强制了路由数据结构必须是以跟节点开始展示, 但业务开发不一定以'/' 开始,可能是一个前端微应用。 也可能是一个常驻路由和业务路由分开的路由。

    const router = [{
    path: '/',
    name: xxx
    children: [xxx]
    }]
  4. 面包屑参考 vue-element-admin

🏞 期望结果 Desired result

  1. 分离菜单底层组件强制绑定的 name
  2. path 非 / 开头的建议使用 fullpath,其实 formatRelativePath 已经实现

🚑 其他信息 Other information

luocong2016 commented 1 year ago

feat: 希望重构路由这部分,写的不是很好。 可以用 hooks 重构下

luocong2016 commented 1 year ago

image

sendya commented 1 year ago

getMenuData 以及 clearMenuItem 均可按照自己业务需求自行实现,并且也推荐自行实现

主要是 Vue 的用法人人都不同,为了照顾大家自己的想法,没办法做到每个点都符合所有人 本来按照 React ProComponents 版本的处理,这里都不暴露 path 直接强制按照 / 开头

并且建议根上的路由都以 / 开头,这跟微服务无关 https://router.vuejs.org/zh/api/#path

luocong2016 commented 1 year ago

@sendya 如果是按照自行实现,如下配置

layout: "mix",
splitMenus: true

存在问题。 image

菜单是被隐藏,激活状态也是错误的。

源码,这里有问题

 const flatMenuData = computed(
 () =>
  (hasFlatMenu.value && props.selectedKeys && getMenuFirstChildren(props.menuData, props.selectedKeys[0])) || []
);

export function getMenuFirstChildren(menus: MenuDataItem[], key?: string) {
  return key === undefined ? [] : (menus[menus.findIndex((menu) => menu.path === key)] || {}).children || [];
}

原因是没找到呀 image

解决问题

  1. selectedKeys 是一个选中遍历 key 集合
const matched = router.currentRoute.value.matched.concat();

 // 我这首页的 name 是 “/”
baseState.selectedKeys = matched
  .filter((r) => r.name !== "/")
  .map((r) => r.path);

baseState.openKeys = matched
   .filter((r) => r.path !== router.currentRoute.value.path)
   .map((r) => r.path);   
luocong2016 commented 1 year ago

数组的根级(第一级)应该是/开始,eslint 其实也会提示

luocong2016 commented 1 year ago
layout: "top"

配置

image

路由结构

image

问题

  1. 刷新后会弹框
  2. 第一次点击也会弹框,抖动 image

可能与路由结构有关系,或者菜单组件。发现是 openKeys 重新写入的时候会被重新打开

解决问题

追踪数据发现 openKeys 居然被重写并展开选中

image

sendya commented 1 year ago

确认一下你的 selectedKeys 是否在变更,selectedKeys 应该是从上往下选中了焦点中的菜单项

/a
   /a/b
       /a/b/c

selectedKeys 应该是 ['/a', '/a/b', '/a/b/c'] 而不是 ['/a/b/c']

luocong2016 commented 1 year ago

@sendya 能再帮我看下 openKeys 的问题吗。感觉这样写不是很好

tzh181129 commented 1 year ago

请问pro-components-vue 菜单使用 ant-design-vue 图标为啥不显示,看例子使用的是自定义图标路径,怎么使用ant-design-vue的图标呢

tzh181129 commented 1 year ago

请问pro-components-vue 菜单使用 ant-design-vue 图标为啥不显示,看例子使用的是自定义图标路径,怎么使用ant-design-vue的图标呢

layout: "top"

配置

image

路由结构

image

问题

  1. 刷新后会弹框
  2. 第一次点击也会弹框,抖动 image

可能与路由结构有关系,或者菜单组件。发现是 openKeys 重新写入的时候会被重新打开

解决问题

追踪数据发现 openKeys 居然被重写并展开选中

image

请问你这里菜单的icon使用的是ant-design-vue的图标吗,请问怎么实现的呀