ソースを参照

feat: 新增useTagsView

kailong321200875 1 年間 前
コミット
75f6cd2ec7

+ 1 - 1
mock/role/index.ts

@@ -300,7 +300,7 @@ const testList: string[] = [
   '/function/multiple-tabs-demo/:id',
   '/hooks',
   '/hooks/useWatermark',
-  '/hooks/useOpenTab',
+  '/hooks/useTagsView',
   // '/hooks/useCrudSchemas',
   '/level',
   '/level/menu1',

+ 2 - 2
src/components/Menu/src/components/useRenderMenuItem.tsx

@@ -6,6 +6,8 @@ import { useRenderMenuTitle } from './useRenderMenuTitle'
 import { useDesign } from '@/hooks/web/useDesign'
 import { pathResolve } from '@/utils/routerHelper'
 
+const { renderMenuTitle } = useRenderMenuTitle()
+
 export const useRenderMenuItem = (
   // allRouters: AppRouteRecordRaw[] = [],
   menuMode: 'vertical' | 'horizontal'
@@ -17,8 +19,6 @@ export const useRenderMenuItem = (
         const { oneShowingChild, onlyOneChild } = hasOneShowingChild(v.children, v)
         const fullPath = isUrl(v.path) ? v.path : pathResolve(parentPath, v.path) // getAllParentPath<AppRouteRecordRaw>(allRouters, v.path).join('/')
 
-        const { renderMenuTitle } = useRenderMenuTitle()
-
         if (
           oneShowingChild &&
           (!onlyOneChild?.children || onlyOneChild?.noShowingChildren) &&

+ 40 - 41
src/components/TagsView/src/TagsView.vue

@@ -12,6 +12,7 @@ import { useDesign } from '@/hooks/web/useDesign'
 import { useTemplateRefsList } from '@vueuse/core'
 import { ElScrollbar } from 'element-plus'
 import { useScrollTo } from '@/hooks/event/useScrollTo'
+import { useTagsView } from '@/hooks/web/useTagsView'
 
 const { getPrefixCls } = useDesign()
 
@@ -19,7 +20,9 @@ const prefixCls = getPrefixCls('tags-view')
 
 const { t } = useI18n()
 
-const { currentRoute, push, replace } = useRouter()
+const { currentRoute, push } = useRouter()
+
+const { closeAll, closeLeft, closeRight, closeOther, closeCurrent, refreshPage } = useTagsView()
 
 const permissionStore = usePermissionStore()
 
@@ -31,6 +34,10 @@ const visitedViews = computed(() => tagsViewStore.getVisitedViews)
 
 const affixTagArr = ref<RouteLocationNormalizedLoaded[]>([])
 
+const selectedTag = computed(() => tagsViewStore.getSelectedTag)
+
+const setSelectTag = tagsViewStore.setSelectedTag
+
 const appStore = useAppStore()
 
 const tagsViewIcon = computed(() => appStore.getTagsViewIcon)
@@ -48,77 +55,68 @@ const initTags = () => {
   }
 }
 
-const selectedTag = ref<RouteLocationNormalizedLoaded>()
-
 // 新增tag
 const addTags = () => {
   const { name } = unref(currentRoute)
   if (name) {
-    selectedTag.value = unref(currentRoute)
+    setSelectTag(unref(currentRoute))
     tagsViewStore.addView(unref(currentRoute))
   }
-  return false
 }
 
 // 关闭选中的tag
 const closeSelectedTag = (view: RouteLocationNormalizedLoaded) => {
-  if (view?.meta?.affix) return
-  tagsViewStore.delView(view)
-  if (isActive(view)) {
-    toLastView()
+  closeCurrent(view, () => {
+    if (isActive(view)) {
+      toLastView()
+    }
+  })
+}
+
+// 去最后一个
+const toLastView = () => {
+  const visitedViews = tagsViewStore.getVisitedViews
+  const latestView = visitedViews.slice(-1)[0]
+  if (latestView) {
+    push(latestView)
+  } else {
+    if (
+      unref(currentRoute).path === permissionStore.getAddRouters[0].path ||
+      unref(currentRoute).path === permissionStore.getAddRouters[0].redirect
+    ) {
+      addTags()
+      return
+    }
+    // You can set another route
+    push(permissionStore.getAddRouters[0].path)
   }
 }
 
 // 关闭全部
 const closeAllTags = () => {
-  tagsViewStore.delAllViews()
-  toLastView()
+  closeAll(() => {
+    toLastView()
+  })
 }
 
 // 关闭其它
 const closeOthersTags = () => {
-  tagsViewStore.delOthersViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
+  closeOther()
 }
 
 // 重新加载
 const refreshSelectedTag = async (view?: RouteLocationNormalizedLoaded) => {
-  if (!view) return
-  tagsViewStore.delCachedView()
-  const { path, query } = view
-  await nextTick()
-  replace({
-    path: '/redirect' + path,
-    query: query
-  })
+  refreshPage(view)
 }
 
 // 关闭左侧
 const closeLeftTags = () => {
-  tagsViewStore.delLeftViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
+  closeLeft()
 }
 
 // 关闭右侧
 const closeRightTags = () => {
-  tagsViewStore.delRightViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
-}
-
-// 跳转到最后一个
-const toLastView = () => {
-  const visitedViews = tagsViewStore.getVisitedViews
-  const latestView = visitedViews.slice(-1)[0]
-  if (latestView) {
-    push(latestView)
-  } else {
-    if (
-      unref(currentRoute).path === permissionStore.getAddRouters[0].path ||
-      unref(currentRoute).path === permissionStore.getAddRouters[0].redirect
-    ) {
-      addTags()
-      return
-    }
-    // You can set another route
-    push(permissionStore.getAddRouters[0].path)
-  }
+  closeRight()
 }
 
 // 滚动到选中的tag
@@ -583,3 +581,4 @@ watch(
   }
 }
 </style>
+@/hooks/web/useTagsView

+ 58 - 0
src/hooks/web/useTagsView.ts

@@ -0,0 +1,58 @@
+import { useTagsViewStoreWithOut } from '@/store/modules/tagsView'
+import { RouteLocationNormalizedLoaded, useRouter } from 'vue-router'
+import { computed, nextTick, unref } from 'vue'
+
+export const useTagsView = () => {
+  const tagsViewStore = useTagsViewStoreWithOut()
+
+  const { replace, currentRoute } = useRouter()
+
+  const selectedTag = computed(() => tagsViewStore.getSelectedTag)
+
+  const closeAll = (callback?: Fn) => {
+    tagsViewStore.delAllViews()
+    callback?.()
+  }
+
+  const closeLeft = (callback?: Fn) => {
+    tagsViewStore.delLeftViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
+    callback?.()
+  }
+
+  const closeRight = (callback?: Fn) => {
+    tagsViewStore.delRightViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
+    callback?.()
+  }
+
+  const closeOther = (callback?: Fn) => {
+    tagsViewStore.delOthersViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
+    callback?.()
+  }
+
+  const closeCurrent = (view?: RouteLocationNormalizedLoaded, callback?: Fn) => {
+    if (view?.meta?.affix) return
+    tagsViewStore.delView(view || unref(currentRoute))
+
+    callback?.()
+  }
+
+  const refreshPage = async (view?: RouteLocationNormalizedLoaded, callback?: Fn) => {
+    tagsViewStore.delCachedView()
+    const { path, query } = view || unref(currentRoute)
+    await nextTick()
+    replace({
+      path: '/redirect' + path,
+      query: query
+    })
+    callback?.()
+  }
+
+  return {
+    closeAll,
+    closeLeft,
+    closeRight,
+    closeOther,
+    closeCurrent,
+    refreshPage
+  }
+}

+ 11 - 2
src/store/modules/tagsView.ts

@@ -8,12 +8,14 @@ import { findIndex } from '@/utils'
 export interface TagsViewState {
   visitedViews: RouteLocationNormalizedLoaded[]
   cachedViews: Set<string>
+  selectedTag?: RouteLocationNormalizedLoaded
 }
 
 export const useTagsViewStore = defineStore('tagsView', {
   state: (): TagsViewState => ({
     visitedViews: [],
-    cachedViews: new Set()
+    cachedViews: new Set(),
+    selectedTag: undefined
   }),
   getters: {
     getVisitedViews(): RouteLocationNormalizedLoaded[] {
@@ -21,6 +23,9 @@ export const useTagsViewStore = defineStore('tagsView', {
     },
     getCachedViews(): string[] {
       return Array.from(this.cachedViews)
+    },
+    getSelectedTag(): RouteLocationNormalizedLoaded | undefined {
+      return this.selectedTag
     }
   },
   actions: {
@@ -85,7 +90,7 @@ export const useTagsViewStore = defineStore('tagsView', {
     // 删除所有tag
     delAllVisitedViews() {
       // const affixTags = this.visitedViews.filter((tag) => tag.meta.affix)
-      this.visitedViews = []
+      this.visitedViews = this.visitedViews.filter((tag) => tag.meta?.affix)
     },
     // 删除其它
     delOthersViews(view: RouteLocationNormalizedLoaded) {
@@ -131,6 +136,10 @@ export const useTagsViewStore = defineStore('tagsView', {
           break
         }
       }
+    },
+    // 设置当前选中的tag
+    setSelectedTag(tag: RouteLocationNormalizedLoaded) {
+      this.selectedTag = tag
     }
   }
 })

+ 50 - 0
src/views/hooks/useTagsView.vue

@@ -0,0 +1,50 @@
+<script setup lang="ts">
+import { ContentWrap } from '@/components/ContentWrap'
+import { ElButton } from 'element-plus'
+import { useTagsView } from '@/hooks/web/useTagsView'
+import { useRouter } from 'vue-router'
+
+const { push } = useRouter()
+
+const { closeAll, closeLeft, closeRight, closeOther, closeCurrent, refreshPage } = useTagsView()
+
+const closeAllTabs = () => {
+  closeAll(() => {
+    push('/dashboard/analysis')
+  })
+}
+
+const closeLeftTabs = () => {
+  closeLeft()
+}
+
+const closeRightTabs = () => {
+  closeRight()
+}
+
+const closeOtherTabs = () => {
+  closeOther()
+}
+
+const refresh = () => {
+  refreshPage()
+}
+
+const closeCurrentTab = () => {
+  closeCurrent(undefined, () => {
+    push('/dashboard/analysis')
+  })
+}
+</script>
+
+<template>
+  <ContentWrap title="useTagsView">
+    <ElButton @click="closeAllTabs"> 关闭所有标签页 </ElButton>
+    <ElButton @click="closeLeftTabs"> 关闭左侧标签页 </ElButton>
+    <ElButton @click="closeRightTabs"> 关闭右侧标签页 </ElButton>
+    <ElButton @click="closeOtherTabs"> 关闭其他标签页 </ElButton>
+    <ElButton @click="closeCurrentTab"> 关闭当前标签页 </ElButton>
+    <ElButton @click="refresh"> 刷新当前标签页 </ElButton>
+  </ContentWrap>
+</template>
+@/hooks/web/useTagsView