menus.ts 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import {computed, ref, Ref, toRaw} from "vue";
  2. import {uiType} from "@/hook/useGraphic";
  3. type MenuRaw = {
  4. key: any,
  5. children?: MenuRaw[]
  6. }
  7. type GenerateResult<R, E = {}> = Array<R & { children: GenerateResult<R, E> } & E>;
  8. export const generateByMenus = <T extends MenuRaw, R>(
  9. generateFn: (men: T) => R,
  10. mainMenus: T[]
  11. ): GenerateResult<R> => {
  12. return mainMenus.map(mainMenu => ({
  13. ...generateFn(mainMenu),
  14. children: mainMenu.children ? generateByMenus(generateFn, mainMenu.children) : []
  15. }))
  16. }
  17. export const findMenuByAttr = <T extends MenuRaw, K extends keyof T, V extends T[K]>
  18. (value: V, attr: K, mainMenus: T[]) => {
  19. for (const mainMenu of mainMenus) {
  20. if (toRaw(mainMenu[attr]) === toRaw(value)) {
  21. return mainMenu
  22. } else if (mainMenu.children) {
  23. const childMainMenu = findMenuByAttr(value, attr as any, mainMenu.children)
  24. if (childMainMenu) {
  25. return childMainMenu;
  26. }
  27. }
  28. }
  29. }
  30. export type GenerateMinMenusResult<TK, R> = {
  31. menus: GenerateResult<R, { onClick: () => void }>,
  32. child: Ref<TK>,
  33. activeMenuKey: Ref<any>
  34. }
  35. export const generateMixMenus = <
  36. T extends MenuRaw,
  37. K extends keyof T,
  38. R
  39. >(
  40. childKey: K,
  41. generateFn: (men: T) => R,
  42. mainMenus: T[],
  43. itemAction: (men: T) => void,
  44. getActiveItem: () => any
  45. ): GenerateMinMenusResult<T[K], R> => {
  46. const child = ref();
  47. const menus = generateByMenus((menu) => ({
  48. ...generateFn(menu),
  49. onClick: () => {
  50. if (menu[childKey]) {
  51. if (toRaw(menu[childKey]) !== toRaw(child.value)) {
  52. child.value = menu[childKey]
  53. return;
  54. }
  55. } else {
  56. itemAction(menu);
  57. }
  58. child.value = null
  59. }
  60. }), mainMenus)
  61. const activeMenuKey = computed(() =>
  62. child.value
  63. ? findMenuByAttr(child.value, childKey, mainMenus)?.key
  64. : getActiveItem()
  65. )
  66. return {
  67. child,
  68. menus,
  69. activeMenuKey
  70. };
  71. }