Kaynağa Gözat

feat: 完成菜单格式化问题

xyh 2 yıl önce
ebeveyn
işleme
e196311210

+ 23 - 52
src/pages/home/menu/hooks.tsx

@@ -1,59 +1,23 @@
-import {type MenuOption, NIcon} from 'naive-ui';
-import {defineComponent, h, reactive, resolveComponent, watch} from 'vue';
-import {HomeTwo} from '@icon-park/vue-next';
+import {type MenuOption} from 'naive-ui';
+import {onMounted, reactive, watch} from 'vue';
 import {useTabStore, storeToRefs} from '@stores';
 import {find} from 'lodash-es';
-import {useRoute, useRouter} from 'vue-router';
+import {useRouter} from 'vue-router';
+import {formatMenu} from '@utils';
 
-const MenuIcon = defineComponent({
-  props: {
-    icon: {type: String, required: true},
-  },
-  setup(props) {
-    const IconComponent = resolveComponent(props.icon) as typeof HomeTwo;
-
-    return function() {
-      return <NIcon>
-        <IconComponent theme="filled" />
-      </NIcon>;
-    };
-  },
-});
-
-function renderIcon(icon: string) {
-  return () => h(MenuIcon, {icon});
-}
+export function useMenu() {
+  const basicMenu = [
+    {title: '首页', id: '-1', img: 'HomeMenuIcon', pid: '0', url: '/main'},
+    {title: '准入审核', id: '1', img: 'HomeMenuIcon', pid: '0', url: ''},
+    {title: '审核列表', id: '2', img: '', pid: '1', url: '/audit'},
+    {title: '准入审批', id: '3', img: '', pid: '1', url: '/audit'},
+    {title: '基础资料', id: '4', img: 'HomeMenuIcon', pid: '0', url: ''},
+    {title: '物料信息', id: '5', img: '', pid: '4', url: '/audit'},
+    {title: 'BOM管理', id: '6', img: '', pid: '4', url: '/audit'},
+  ];
 
-export const menuOptions: MenuOption[] = [
-  {
-    label: '首页',
-    key: '-1',
-    icon: renderIcon('HomeMenuIcon'),
-    pid: '0',
-    url: '/',
-  },
-  {
-    label: '准入审核',
-    key: '1',
-    icon: renderIcon('HomeMenuIcon'),
-    pid: '0',
-    children: [
-      {label: '审核列表', key: '2', pid: '1', url: '/audit'},
-      {label: '准入审批', key: '3', pid: '1', url: '/audit'},
-    ],
-  },
-  {
-    label: '基础资料',
-    key: '4',
-    icon: renderIcon('HomeMenuIcon'),
-    children: [
-      {label: '物料信息', key: '5', pid: '4', url: '/audit'},
-      {label: 'BOM管理', key: '6', pid: '4', url: '/audit'},
-    ],
-  },
-];
+  const menuOptions = formatMenu(basicMenu);
 
-export function useMenu() {
   const tabStore = useTabStore();
   const {activeKey, tabList} = storeToRefs(tabStore);
   const expandKeys = reactive<string[]>([]);
@@ -80,6 +44,10 @@ export function useMenu() {
     });
   }
 
+  onMounted(function() {
+    // 页面初始页面不一定是首页需要判断是否需要增加tab
+  });
+
   // activeKey变化后更新菜单的展开菜单的值并跳转到对应的url
   watch(activeKey, function(value) {
     if (expandKeys[0] === value) return;
@@ -94,5 +62,8 @@ export function useMenu() {
     push(temp.url);
   });
 
-  return [{activeKey, expandKeys}, {onUpdate, onExpandedUpdate}] as const;
+  return [
+    {activeKey, expandKeys, menuOptions},
+    {onUpdate, onExpandedUpdate},
+  ] as const;
 }

+ 75 - 0
src/utils/format-menu/index.tsx

@@ -0,0 +1,75 @@
+import {HomeTwo} from '@icon-park/vue-next';
+import {NIcon} from 'naive-ui';
+import {VNodeChild, defineComponent, h, resolveComponent} from 'vue';
+
+export type MenuList = {
+  label: string,
+  key: string,
+  icon?: () => VNodeChild,
+  pid: string,
+  url: string,
+  children?: MenuList[],
+};
+
+const MenuIcon = defineComponent({
+  props: {
+    icon: {type: String, required: true},
+  },
+  setup(props) {
+    if (!props.icon) return null;
+
+    const IconComponent = resolveComponent(props.icon) as typeof HomeTwo;
+
+    return function() {
+      return <NIcon>
+        <IconComponent theme="filled" />
+      </NIcon>;
+    };
+  },
+});
+
+function renderIcon(icon: string) {
+  return () => h(MenuIcon, {icon});
+}
+
+export function formatMenu(menus: Record<string, string>[]) {
+  const result: MenuList[] = [];
+  const tempArea = new Map<string, MenuList[]>();
+
+  menus.forEach(function({title, id, img, pid, url}) {
+    const temp: MenuList = {
+      label: title,
+      key: id,
+      pid,
+      url,
+    };
+
+    img && (temp.icon = renderIcon(img));
+
+    // 判断是否有pid 如果pid不为0说明为二级菜单
+    if (pid === '0') {
+      // 判断临时区域有没有对应的二级菜单
+      const children = tempArea.get(id);
+
+      children && (temp.children = children);
+
+      result.push(temp);
+    } else {
+      // 如果能在数组中能找到父级菜单直接插入到children中
+      // 如果找不到放到临时区域等待父组件挂载
+      const idx = result.findIndex(val => val.key === pid);
+
+      if (idx >= 0) {
+        result[idx].children
+          ? result[idx].children!.push(temp)
+          : result[idx].children = [temp];
+      } else {
+        tempArea.has(pid)
+          ? tempArea.get(pid)!.push(temp)
+          : tempArea.set(pid, [temp]);
+      }
+    }
+  });
+
+  return result;
+}

+ 1 - 0
src/utils/index.ts

@@ -1,3 +1,4 @@
 export * from './validate-tips';
 export * from './theme';
 export * from './constants';
+export * from './format-menu';