main-hooks.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import { onBeforeUnmount, provide, ref } from 'vue'
  2. import { useRoute } from 'vue-router'
  3. import { isArray } from '@cip/utils/util'
  4. // 菜单徽标hook
  5. /**
  6. * 定时更新时间
  7. * @param timer 为0时不进行更新 单位ms
  8. * @return {{badgeMap: ToRef<{}>, badgeFnMap: ToRef<{}>, collectBadgeFn: collectBadgeFn, consumptionBadgeFn: ((function(*): Promise<void>)|*)}}
  9. */
  10. export const useBadge = (times) => {
  11. const badgeMap = ref({}) // 徽标key-value关系
  12. const badgeFnMap = ref({}) // 徽标key-fn关系
  13. const collectBadgeFn = (menu = [], { key, fnKey, childrenKey = 'children' }) => {
  14. menu.forEach(item => {
  15. const fn = item?.[fnKey]
  16. if (typeof fn === 'function') {
  17. badgeFnMap.value[item[key]] = { fn, used: false, privilege: false }
  18. }
  19. const children = item[childrenKey]
  20. if (isArray(children)) {
  21. collectBadgeFn(children, { key, fnKey, childrenKey })
  22. }
  23. })
  24. }
  25. // 定时更新时使用
  26. const resetComputed = () => {
  27. Object.keys(badgeFnMap.value).forEach(key => {
  28. badgeFnMap.value[key].used = false
  29. // !!!有权限的菜单的badge方法才会执行
  30. if (badgeFnMap.value[key].privilege) {
  31. consumptionBadgeFn(key)
  32. }
  33. })
  34. }
  35. if (times > 0) {
  36. const timer = setInterval(() => {
  37. resetComputed()
  38. }, times)
  39. onBeforeUnmount(() => {
  40. clearInterval(timer)
  41. })
  42. }
  43. const consumptionBadgeFn = async (key) => {
  44. const badgeFn = badgeFnMap.value?.[key]
  45. if (badgeFn && !badgeFn.used) {
  46. badgeFn.used = true // 删除防止多次触发
  47. badgeFn.privilege = true // 触发过一次及判断为拥有权限
  48. const total = await badgeFn.fn()
  49. badgeMap.value[key] = total
  50. }
  51. }
  52. const setBadge = (key, badge) => {
  53. badgeMap.value[key] = badge
  54. }
  55. // 子孙组件直接修改徽标
  56. provide('setBadge', setBadge)
  57. const refreshBadge = (key) => {
  58. const badgeFn = badgeFnMap.value?.[key]
  59. if (badgeFn) {
  60. badgeFn.used = false // 先把used设置为false才能触发更新
  61. consumptionBadgeFn(key)
  62. }
  63. }
  64. // 子孙组件根据触发修改徽标
  65. provide('refreshBadge', refreshBadge)
  66. return {
  67. badgeMap,
  68. badgeFnMap,
  69. collectBadgeFn,
  70. consumptionBadgeFn
  71. }
  72. }
  73. export const useMenuTitle = () => {
  74. const route = useRoute()
  75. const menuNameMap = ref(new Map()) // name 与 title 的关系
  76. const menuPathMap = ref({}) // fullPath 与 title 的关系
  77. const setCurrentTitle = (title) => {
  78. setTitle(route.fullPath, route.name, title)
  79. }
  80. const setTitle = (fullPath, name, title) => {
  81. menuNameMap.value.set(name, title)
  82. menuPathMap.value[fullPath] = title
  83. }
  84. // 兼容老代码[addMenuName]不建议再使用
  85. provide('addMenuName', setCurrentTitle)
  86. provide('setCurrentTitle', setCurrentTitle)
  87. provide('setTitle', setTitle)
  88. return {
  89. menuNameMap,
  90. menuPathMap
  91. }
  92. }