menus.ts 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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: MenuRaw) => void
  44. ): GenerateMinMenusResult<T[K], R> => {
  45. const child = ref();
  46. const menus = generateByMenus((menu) => ({
  47. ...generateFn(menu),
  48. onClick: () => {
  49. if (menu[childKey]) {
  50. if (toRaw(menu[childKey]) !== toRaw(child.value)) {
  51. child.value = menu[childKey]
  52. return;
  53. }
  54. } else {
  55. itemAction(menu);
  56. }
  57. child.value = null
  58. }
  59. }), mainMenus)
  60. const activeMenuKey = computed(() =>
  61. child.value
  62. ? findMenuByAttr(child.value, childKey, mainMenus)?.key
  63. : uiType.current
  64. )
  65. return {
  66. child,
  67. menus,
  68. activeMenuKey
  69. };
  70. }