feat: 新增useTagsView
This commit is contained in:
parent
7a2b3a9d84
commit
a869a457e6
|
@ -323,11 +323,11 @@ const adminList = [
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'useOpenTab',
|
path: 'useTagsView',
|
||||||
component: 'views/hooks/useOpenTab',
|
component: 'views/hooks/useTagsView',
|
||||||
name: 'UseOpenTab',
|
name: 'UseTagsView',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'useOpenTab'
|
title: 'useTagsView'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// {
|
// {
|
||||||
|
@ -597,7 +597,7 @@ const testList: string[] = [
|
||||||
'/function/multiple-tabs-demo/:id',
|
'/function/multiple-tabs-demo/:id',
|
||||||
'/hooks',
|
'/hooks',
|
||||||
'/hooks/useWatermark',
|
'/hooks/useWatermark',
|
||||||
'/hooks/useOpenTab',
|
'/hooks/useTagsView',
|
||||||
// '/hooks/useCrudSchemas',
|
// '/hooks/useCrudSchemas',
|
||||||
'/level',
|
'/level',
|
||||||
'/level/menu1',
|
'/level/menu1',
|
||||||
|
|
|
@ -6,6 +6,8 @@ import { useRenderMenuTitle } from './useRenderMenuTitle'
|
||||||
import { useDesign } from '@/hooks/web/useDesign'
|
import { useDesign } from '@/hooks/web/useDesign'
|
||||||
import { pathResolve } from '@/utils/routerHelper'
|
import { pathResolve } from '@/utils/routerHelper'
|
||||||
|
|
||||||
|
const { renderMenuTitle } = useRenderMenuTitle()
|
||||||
|
|
||||||
export const useRenderMenuItem = (
|
export const useRenderMenuItem = (
|
||||||
// allRouters: AppRouteRecordRaw[] = [],
|
// allRouters: AppRouteRecordRaw[] = [],
|
||||||
menuMode: 'vertical' | 'horizontal'
|
menuMode: 'vertical' | 'horizontal'
|
||||||
|
@ -17,8 +19,6 @@ export const useRenderMenuItem = (
|
||||||
const { oneShowingChild, onlyOneChild } = hasOneShowingChild(v.children, v)
|
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 fullPath = isUrl(v.path) ? v.path : pathResolve(parentPath, v.path) // getAllParentPath<AppRouteRecordRaw>(allRouters, v.path).join('/')
|
||||||
|
|
||||||
const { renderMenuTitle } = useRenderMenuTitle()
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
oneShowingChild &&
|
oneShowingChild &&
|
||||||
(!onlyOneChild?.children || onlyOneChild?.noShowingChildren) &&
|
(!onlyOneChild?.children || onlyOneChild?.noShowingChildren) &&
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { useDesign } from '@/hooks/web/useDesign'
|
||||||
import { useTemplateRefsList } from '@vueuse/core'
|
import { useTemplateRefsList } from '@vueuse/core'
|
||||||
import { ElScrollbar } from 'element-plus'
|
import { ElScrollbar } from 'element-plus'
|
||||||
import { useScrollTo } from '@/hooks/event/useScrollTo'
|
import { useScrollTo } from '@/hooks/event/useScrollTo'
|
||||||
|
import { useTagsView } from '@/hooks/web/useTagsView'
|
||||||
|
|
||||||
const { getPrefixCls } = useDesign()
|
const { getPrefixCls } = useDesign()
|
||||||
|
|
||||||
|
@ -19,7 +20,9 @@ const prefixCls = getPrefixCls('tags-view')
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
const { currentRoute, push, replace } = useRouter()
|
const { currentRoute, push } = useRouter()
|
||||||
|
|
||||||
|
const { closeAll, closeLeft, closeRight, closeOther, closeCurrent, refreshPage } = useTagsView()
|
||||||
|
|
||||||
const permissionStore = usePermissionStore()
|
const permissionStore = usePermissionStore()
|
||||||
|
|
||||||
|
@ -31,6 +34,10 @@ const visitedViews = computed(() => tagsViewStore.getVisitedViews)
|
||||||
|
|
||||||
const affixTagArr = ref<RouteLocationNormalizedLoaded[]>([])
|
const affixTagArr = ref<RouteLocationNormalizedLoaded[]>([])
|
||||||
|
|
||||||
|
const selectedTag = computed(() => tagsViewStore.getSelectedTag)
|
||||||
|
|
||||||
|
const setSelectTag = tagsViewStore.setSelectedTag
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
|
|
||||||
const tagsViewIcon = computed(() => appStore.getTagsViewIcon)
|
const tagsViewIcon = computed(() => appStore.getTagsViewIcon)
|
||||||
|
@ -48,61 +55,25 @@ const initTags = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const selectedTag = ref<RouteLocationNormalizedLoaded>()
|
|
||||||
|
|
||||||
// 新增tag
|
// 新增tag
|
||||||
const addTags = () => {
|
const addTags = () => {
|
||||||
const { name } = unref(currentRoute)
|
const { name } = unref(currentRoute)
|
||||||
if (name) {
|
if (name) {
|
||||||
selectedTag.value = unref(currentRoute)
|
setSelectTag(unref(currentRoute))
|
||||||
tagsViewStore.addView(unref(currentRoute))
|
tagsViewStore.addView(unref(currentRoute))
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭选中的tag
|
// 关闭选中的tag
|
||||||
const closeSelectedTag = (view: RouteLocationNormalizedLoaded) => {
|
const closeSelectedTag = (view: RouteLocationNormalizedLoaded) => {
|
||||||
if (view?.meta?.affix) return
|
closeCurrent(view, () => {
|
||||||
tagsViewStore.delView(view)
|
if (isActive(view)) {
|
||||||
if (isActive(view)) {
|
toLastView()
|
||||||
toLastView()
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭全部
|
|
||||||
const closeAllTags = () => {
|
|
||||||
tagsViewStore.delAllViews()
|
|
||||||
toLastView()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭其它
|
|
||||||
const closeOthersTags = () => {
|
|
||||||
tagsViewStore.delOthersViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 重新加载
|
|
||||||
const refreshSelectedTag = async (view?: RouteLocationNormalizedLoaded) => {
|
|
||||||
if (!view) return
|
|
||||||
tagsViewStore.delCachedView()
|
|
||||||
const { path, query } = view
|
|
||||||
await nextTick()
|
|
||||||
replace({
|
|
||||||
path: '/redirect' + path,
|
|
||||||
query: query
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭左侧
|
// 去最后一个
|
||||||
const closeLeftTags = () => {
|
|
||||||
tagsViewStore.delLeftViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 关闭右侧
|
|
||||||
const closeRightTags = () => {
|
|
||||||
tagsViewStore.delRightViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 跳转到最后一个
|
|
||||||
const toLastView = () => {
|
const toLastView = () => {
|
||||||
const visitedViews = tagsViewStore.getVisitedViews
|
const visitedViews = tagsViewStore.getVisitedViews
|
||||||
const latestView = visitedViews.slice(-1)[0]
|
const latestView = visitedViews.slice(-1)[0]
|
||||||
|
@ -121,6 +92,33 @@ const toLastView = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 关闭全部
|
||||||
|
const closeAllTags = () => {
|
||||||
|
closeAll(() => {
|
||||||
|
toLastView()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭其它
|
||||||
|
const closeOthersTags = () => {
|
||||||
|
closeOther()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新加载
|
||||||
|
const refreshSelectedTag = async (view?: RouteLocationNormalizedLoaded) => {
|
||||||
|
refreshPage(view)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭左侧
|
||||||
|
const closeLeftTags = () => {
|
||||||
|
closeLeft()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭右侧
|
||||||
|
const closeRightTags = () => {
|
||||||
|
closeRight()
|
||||||
|
}
|
||||||
|
|
||||||
// 滚动到选中的tag
|
// 滚动到选中的tag
|
||||||
const moveToCurrentTag = async () => {
|
const moveToCurrentTag = async () => {
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
@ -583,3 +581,4 @@ watch(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@/hooks/web/useTagsView
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -362,6 +362,14 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
|
||||||
meta: {
|
meta: {
|
||||||
title: 'useWatermark'
|
title: 'useWatermark'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'useTagsView',
|
||||||
|
component: () => import('@/views/hooks/useTagsView.vue'),
|
||||||
|
name: 'UseTagsView',
|
||||||
|
meta: {
|
||||||
|
title: 'useTagsView'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// {
|
// {
|
||||||
// path: 'useCrudSchemas',
|
// path: 'useCrudSchemas',
|
||||||
|
|
|
@ -8,12 +8,14 @@ import { findIndex } from '@/utils'
|
||||||
export interface TagsViewState {
|
export interface TagsViewState {
|
||||||
visitedViews: RouteLocationNormalizedLoaded[]
|
visitedViews: RouteLocationNormalizedLoaded[]
|
||||||
cachedViews: Set<string>
|
cachedViews: Set<string>
|
||||||
|
selectedTag?: RouteLocationNormalizedLoaded
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useTagsViewStore = defineStore('tagsView', {
|
export const useTagsViewStore = defineStore('tagsView', {
|
||||||
state: (): TagsViewState => ({
|
state: (): TagsViewState => ({
|
||||||
visitedViews: [],
|
visitedViews: [],
|
||||||
cachedViews: new Set()
|
cachedViews: new Set(),
|
||||||
|
selectedTag: undefined
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
getVisitedViews(): RouteLocationNormalizedLoaded[] {
|
getVisitedViews(): RouteLocationNormalizedLoaded[] {
|
||||||
|
@ -21,6 +23,9 @@ export const useTagsViewStore = defineStore('tagsView', {
|
||||||
},
|
},
|
||||||
getCachedViews(): string[] {
|
getCachedViews(): string[] {
|
||||||
return Array.from(this.cachedViews)
|
return Array.from(this.cachedViews)
|
||||||
|
},
|
||||||
|
getSelectedTag(): RouteLocationNormalizedLoaded | undefined {
|
||||||
|
return this.selectedTag
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -85,7 +90,7 @@ export const useTagsViewStore = defineStore('tagsView', {
|
||||||
// 删除所有tag
|
// 删除所有tag
|
||||||
delAllVisitedViews() {
|
delAllVisitedViews() {
|
||||||
// const affixTags = this.visitedViews.filter((tag) => tag.meta.affix)
|
// const affixTags = this.visitedViews.filter((tag) => tag.meta.affix)
|
||||||
this.visitedViews = []
|
this.visitedViews = this.visitedViews.filter((tag) => tag.meta?.affix)
|
||||||
},
|
},
|
||||||
// 删除其它
|
// 删除其它
|
||||||
delOthersViews(view: RouteLocationNormalizedLoaded) {
|
delOthersViews(view: RouteLocationNormalizedLoaded) {
|
||||||
|
@ -131,6 +136,10 @@ export const useTagsViewStore = defineStore('tagsView', {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
// 设置当前选中的tag
|
||||||
|
setSelectedTag(tag: RouteLocationNormalizedLoaded) {
|
||||||
|
this.selectedTag = tag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue