hooks.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import { ref, unref, watch } from 'vue'
  2. import { useRouter, useRoute } from 'vue-router'
  3. const findViewIndex = (viewList, view) => {
  4. return viewList.findIndex(v => v.fullPath === view.fullPath)
  5. }
  6. export const useCacheView = (updateCache) => {
  7. const cacheViewList = ref([])
  8. // 添加
  9. const addCacheView = (path) => {
  10. // 判断是否需要添加
  11. if (!cacheViewList.value.includes(path)) {
  12. cacheViewList.value.push(path)
  13. updateCache(cacheViewList.value)
  14. }
  15. }
  16. // 删除
  17. const removeCacheView = (path) => {
  18. const index = cacheViewList.value.indexOf(path)
  19. if (index > -1) {
  20. cacheViewList.value.splice(index, 1)
  21. updateCache(cacheViewList.value)
  22. }
  23. }
  24. // 重置
  25. const resetCacheList = () => {
  26. cacheViewList.value = []
  27. updateCache(cacheViewList.value)
  28. }
  29. return {
  30. cacheViewList,
  31. addCacheView,
  32. removeCacheView,
  33. resetCacheList
  34. }
  35. }
  36. export const useActiveOrder = () => {
  37. const activeOrderList = ref([])
  38. const updateActiveOrder = (view) => {
  39. const activeIndex = findViewIndex(activeOrderList.value, view)
  40. if (activeIndex > -1) activeOrderList.value.splice(activeIndex, 1)
  41. activeOrderList.value.push(view)
  42. }
  43. const removeActiveOrder = (view) => {
  44. const activeIndex = findViewIndex(activeOrderList.value, view)
  45. if (activeIndex > -1) activeOrderList.value.splice(activeIndex, 1)
  46. }
  47. const resetActiveOrderList = () => {
  48. activeOrderList.value = []
  49. }
  50. const getNextActiveOrder = () => {
  51. const activeOrderListLength = activeOrderList.value.length
  52. if (activeOrderListLength > 2) {
  53. return activeOrderList.value[activeOrderListLength - 2]
  54. }
  55. }
  56. return {
  57. activeOrderList,
  58. updateActiveOrder,
  59. removeActiveOrder,
  60. resetActiveOrderList,
  61. getNextActiveOrder
  62. }
  63. }
  64. // activeView - ref({}) 当前激活的路由
  65. export const useOpenedView = (homeView) => {
  66. const router = useRouter()
  67. const route = useRoute()
  68. const activeView = ref({})
  69. const { updateActiveOrder, removeActiveOrder, resetActiveOrderList, getNextActiveOrder } = useActiveOrder()
  70. const isActiveView = (view) => {
  71. return unref(activeView).fullPath === view?.fullPath
  72. }
  73. const setActiveView = (view) => {
  74. activeView.value = view
  75. router.push(view.fullPath ?? view)
  76. }
  77. // TODO: 考虑固定打开的ViewList
  78. const openedViewList = ref([]) // 不再提供
  79. const getHomeView = () => {
  80. // 下一个为当前路由match的上一个
  81. if (homeView) {
  82. // 下一个为指定的首页
  83. return homeView
  84. } else {
  85. if (route.matched.length > 1) {
  86. return route.matched[route.matched.length - 2] // ()
  87. } else {
  88. return route.matched[0]
  89. }
  90. }
  91. }
  92. const getNextActiveView = () => {
  93. let nextActive = getNextActiveOrder()
  94. if (!nextActive) {
  95. // 如果已经是最后一个了(一般情况不允许删除), 特殊情况允许返回首页
  96. nextActive = getHomeView()
  97. }
  98. return nextActive
  99. }
  100. watch(activeView, (val) => {
  101. updateActiveOrder(val)
  102. }, { immediate: true })
  103. // 添加一个视图
  104. const addOpenedView = (view) => {
  105. openedViewList.value.push(view)
  106. setActiveView(view)
  107. }
  108. // 修改一个视图
  109. const updateOpenedView = (index, view) => {
  110. openedViewList.value.splice(index, 1, view)
  111. setActiveView(view)
  112. }
  113. // 关闭一个视图
  114. const removeOpenedView = (view) => {
  115. if (isActiveView(view)) setActiveView(getNextActiveView()) // 获取上一个激活的
  116. // 删除openedView时需要同时删除opened和active
  117. const index = findViewIndex(openedViewList.value, view)
  118. if (index > -1)openedViewList.value.splice(index, 1)
  119. removeActiveOrder(view)
  120. }
  121. // 关闭其他视图 view允许为空
  122. const removeOtherView = (view) => {
  123. if (!isActiveView(view)) {
  124. setActiveView(view)
  125. }
  126. openedViewList.value = [activeView.value]
  127. }
  128. const findViewByOpenedViewList = (fullPath) => {
  129. return openedViewList.value.find(openedView => openedView.fullPath === fullPath)
  130. }
  131. // 关闭所有
  132. const resetOpenedList = () => {
  133. resetActiveOrderList()
  134. // if (homeView) {
  135. openedViewList.value = [getHomeView()]
  136. setActiveView(getHomeView())
  137. // } else {
  138. // // 默认方案
  139. // openedViewList.value = [{ fullPath: '/', title: '首页' }]
  140. // setActiveView({ fullPath: '/', title: '首页' })
  141. // }
  142. }
  143. return {
  144. activeView,
  145. openedViewList,
  146. addOpenedView,
  147. updateOpenedView,
  148. removeOpenedView,
  149. removeOtherView,
  150. resetOpenedList,
  151. setActiveView,
  152. findViewByOpenedViewList
  153. }
  154. }