diff --git a/src/hooks/web/useTagsView.ts b/src/hooks/web/useTagsView.ts new file mode 100644 index 0000000000000000000000000000000000000000..31eadb027d79a0e1edc436cb07905e3044d11ea8 --- /dev/null +++ b/src/hooks/web/useTagsView.ts @@ -0,0 +1,63 @@ +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?.() + } + + const setTitle = (title: string, path?: string) => { + tagsViewStore.setTitle(title, path) + } + + return { + closeAll, + closeLeft, + closeRight, + closeOther, + closeCurrent, + refreshPage, + setTitle + } +} diff --git a/src/layout/components/TagsView/src/TagsView.vue b/src/layout/components/TagsView/src/TagsView.vue index 4770989fc49a6050ed7e2338f4cbe6b084f92d47..692aef1140e19dfbb9e43e1511ea7cb4e10b67b4 100644 --- a/src/layout/components/TagsView/src/TagsView.vue +++ b/src/layout/components/TagsView/src/TagsView.vue @@ -12,6 +12,8 @@ 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' +import { cloneDeep } from 'lodash-es' const { getPrefixCls } = useDesign() @@ -19,7 +21,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 +35,10 @@ const visitedViews = computed(() => tagsViewStore.getVisitedViews) const affixTagArr = ref([]) +const selectedTag = computed(() => tagsViewStore.getSelectedTag) + +const setSelectTag = tagsViewStore.setSelectedTag + const appStore = useAppStore() const tagsViewIcon = computed(() => appStore.getTagsViewIcon) @@ -43,82 +51,73 @@ const initTags = () => { for (const tag of unref(affixTagArr)) { // Must have tag name if (tag.name) { - tagsViewStore.addVisitedView(tag) + tagsViewStore.addVisitedView(cloneDeep(tag)) } } } -const selectedTag = ref() - // 新增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 - } - // TODO: You can set another route - push('/') - } + closeRight() } // 滚动到选中的tag diff --git a/src/store/modules/tagsView.ts b/src/store/modules/tagsView.ts index a60d0e453943d8e77b1c09b9ddc2625ffd4c0fbd..9cfea42dec37c94998d913b4aa4f2dea8fb76305 100644 --- a/src/store/modules/tagsView.ts +++ b/src/store/modules/tagsView.ts @@ -2,18 +2,20 @@ import router from '@/router' import type { RouteLocationNormalizedLoaded } from 'vue-router' import { getRawRoute } from '@/utils/routerHelper' import { defineStore } from 'pinia' -import { store } from '../index' +import { store } from '@/store' import { findIndex } from '@/utils' export interface TagsViewState { visitedViews: RouteLocationNormalizedLoaded[] cachedViews: Set + 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: { @@ -58,7 +63,7 @@ export const useTagsViewStore = defineStore('tagsView', { // 删除某个 delView(view: RouteLocationNormalizedLoaded) { this.delVisitedView(view) - this.delCachedView() + this.addCachedView() }, // 删除tag delVisitedView(view: RouteLocationNormalizedLoaded) { @@ -80,19 +85,19 @@ export const useTagsViewStore = defineStore('tagsView', { // 删除所有缓存和tag delAllViews() { this.delAllVisitedViews() - this.delCachedView() + this.addCachedView() }, // 删除所有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) { this.delOthersVisitedViews(view) this.addCachedView() }, - // 删除其他tag + // 删除其它tag delOthersVisitedViews(view: RouteLocationNormalizedLoaded) { this.visitedViews = this.visitedViews.filter((v) => { return v?.meta?.affix || v.path === view.path @@ -131,6 +136,18 @@ export const useTagsViewStore = defineStore('tagsView', { break } } + }, + // 设置当前选中的tag + setSelectedTag(tag: RouteLocationNormalizedLoaded) { + this.selectedTag = tag + }, + setTitle(title: string, path?: string) { + for (const v of this.visitedViews) { + if (v.path === (path ?? this.selectedTag?.path)) { + v.meta.title = title + break + } + } } } })