diff --git a/apps/web-antd/src/forward/request.ts b/apps/web-antd/src/forward/request.ts index cb69ad87..a01de8fe 100644 --- a/apps/web-antd/src/forward/request.ts +++ b/apps/web-antd/src/forward/request.ts @@ -33,8 +33,8 @@ function createRequestClient() { // 这里不能用 useAccessStore,因为 useAccessStore 会导致循环引用 const accessStore = useCoreAccessStore(); return { - refreshToken: `Bearer ${accessStore.getRefreshToken}`, - token: `Bearer ${accessStore.getAccessToken}`, + refreshToken: `Bearer ${accessStore.refreshToken}`, + token: `Bearer ${accessStore.accessToken}`, }; }, // 默认 diff --git a/apps/web-antd/src/store/modules/access.ts b/apps/web-antd/src/store/modules/access.ts index 5d979424..a17979c2 100644 --- a/apps/web-antd/src/store/modules/access.ts +++ b/apps/web-antd/src/store/modules/access.ts @@ -17,10 +17,10 @@ export const useAccessStore = defineStore('access', () => { const router = useRouter(); const loading = ref(false); - const accessToken = computed(() => coreStoreAccess.getAccessToken); - const userRoles = computed(() => coreStoreAccess.getUserRoles); - const userInfo = computed(() => coreStoreAccess.getUserInfo); - const accessRoutes = computed(() => coreStoreAccess.getAccessRoutes); + const accessToken = computed(() => coreStoreAccess.accessToken); + const userRoles = computed(() => coreStoreAccess.userRoles); + const userInfo = computed(() => coreStoreAccess.userInfo); + const accessRoutes = computed(() => coreStoreAccess.accessRoutes); function setAccessMenus(menus: MenuRecordRaw[]) { coreStoreAccess.setAccessMenus(menus); diff --git a/packages/@core/forward/preferences/src/config.ts b/packages/@core/forward/preferences/src/config.ts index e6bcd10f..82519d9f 100644 --- a/packages/@core/forward/preferences/src/config.ts +++ b/packages/@core/forward/preferences/src/config.ts @@ -71,6 +71,7 @@ const defaultPreferences: Preferences = { tabbar: { enable: true, keepAlive: true, + persist: true, showIcon: true, }, theme: { diff --git a/packages/@core/forward/preferences/src/types.ts b/packages/@core/forward/preferences/src/types.ts index 00b6db44..0c9d04b6 100644 --- a/packages/@core/forward/preferences/src/types.ts +++ b/packages/@core/forward/preferences/src/types.ts @@ -143,6 +143,8 @@ interface TabbarPreferences { enable: boolean; /** 开启标签页缓存功能 */ keepAlive: boolean; + /** 是否持久化标签 */ + persist: boolean; /** 是否开启多标签页图标 */ showIcon: boolean; } diff --git a/packages/@core/forward/stores/src/modules/access.test.ts b/packages/@core/forward/stores/src/modules/access.test.ts index c3b5dc8e..f8774fcf 100644 --- a/packages/@core/forward/stores/src/modules/access.test.ts +++ b/packages/@core/forward/stores/src/modules/access.test.ts @@ -33,7 +33,7 @@ describe('useCoreAccessStore', () => { const store = useCoreAccessStore(); const userInfo: any = { name: 'Jane Doe', roles: [{ value: 'user' }] }; store.setUserInfo(userInfo); - expect(store.getUserInfo).toEqual(userInfo); + expect(store.userInfo).toEqual(userInfo); }); it('updates accessToken state correctly', () => { @@ -60,13 +60,13 @@ describe('useCoreAccessStore', () => { it('returns the correct accessToken', () => { const store = useCoreAccessStore(); store.setAccessToken('xyz789'); - expect(store.getAccessToken).toBe('xyz789'); + expect(store.accessToken).toBe('xyz789'); }); // 测试在没有用户角色时返回空数组 it('returns an empty array for userRoles if not set', () => { const store = useCoreAccessStore(); - expect(store.getUserRoles).toEqual([]); + expect(store.userRoles).toEqual([]); }); // 测试设置空的访问菜单列表 diff --git a/packages/@core/forward/stores/src/modules/access.ts b/packages/@core/forward/stores/src/modules/access.ts index c3455034..e29b6b69 100644 --- a/packages/@core/forward/stores/src/modules/access.ts +++ b/packages/@core/forward/stores/src/modules/access.ts @@ -90,32 +90,6 @@ const useCoreAccessStore = defineStore('core-access', { this.userRoles = roles; }, }, - getters: { - getAccessCodes(): string[] { - return this.accessCodes; - }, - getAccessMenus(): MenuRecordRaw[] { - return this.accessMenus; - }, - getAccessRoutes(): RouteRecordRaw[] { - return this.accessRoutes; - }, - getAccessToken(): AccessToken { - return this.accessToken; - }, - getRefreshToken(): AccessToken { - return this.refreshToken; - }, - getUserInfo(): BasicUserInfo | null { - return this.userInfo; - }, - getUserRoles(): string[] { - return this.userRoles; - }, - string(): string[] { - return this.accessCodes; - }, - }, persist: { // 持久化 paths: ['accessToken', 'refreshToken', 'accessCodes'], diff --git a/packages/@core/forward/stores/src/modules/tabbar.test.ts b/packages/@core/forward/stores/src/modules/tabbar.test.ts index a9016b69..a9974acf 100644 --- a/packages/@core/forward/stores/src/modules/tabbar.test.ts +++ b/packages/@core/forward/stores/src/modules/tabbar.test.ts @@ -99,9 +99,9 @@ describe('useCoreAccessStore', () => { it('returns all cache tabs', () => { const store = useCoreTabbarStore(); - store.cacheTabs.add('Home'); - store.cacheTabs.add('About'); - expect(store.getCacheTabs).toEqual(['Home', 'About']); + store.cachedTabs.add('Home'); + store.cachedTabs.add('About'); + expect(store.cachedTabs).toEqual(['Home', 'About']); }); it('returns all tabs, including affix tabs', () => { @@ -290,7 +290,7 @@ describe('useCoreAccessStore', () => { await store.refresh(router); - expect(store.excludeCacheTabs.has('Dashboard')).toBe(false); + expect(store.excludeCachedTabs.has('Dashboard')).toBe(false); expect(store.renderRouteView).toBe(true); }); }); diff --git a/packages/@core/forward/stores/src/modules/tabbar.ts b/packages/@core/forward/stores/src/modules/tabbar.ts index dec3b99d..e9a44f28 100644 --- a/packages/@core/forward/stores/src/modules/tabbar.ts +++ b/packages/@core/forward/stores/src/modules/tabbar.ts @@ -7,60 +7,15 @@ import { startProgress, stopProgress } from '@vben-core/toolkit'; import { acceptHMRUpdate, defineStore } from 'pinia'; -/** - * @zh_CN 克隆路由,防止路由被修改 - * @param route - */ -function cloneTab(route: TabItem): TabItem { - if (!route) { - return route; - } - const { matched, ...opt } = route; - return { - ...opt, - matched: (matched - ? matched.map((item) => ({ - meta: item.meta, - name: item.name, - path: item.path, - })) - : undefined) as RouteRecordNormalized[], - }; -} - -/** - * @zh_CN 是否是固定标签页 - * @param tab - */ -function isAffixTab(tab: TabItem) { - return tab.meta?.affixTab ?? false; -} - -/** - * @zh_CN 是否显示标签 - * @param tab - */ -function isTabShow(tab: TabItem) { - return !tab.meta.hideInTab; -} - -function routeToTab(route: RouteRecordNormalized) { - return { - meta: route.meta, - name: route.name, - path: route.path, - } as unknown as TabItem; -} - interface TabsState { /** * @zh_CN 当前打开的标签页列表缓存 */ - cacheTabs: Set; + cachedTabs: Set; /** * @zh_CN 需要排除缓存的标签页 */ - excludeCacheTabs: Set; + excludeCachedTabs: Set; /** * @zh_CN 是否刷新 */ @@ -81,7 +36,7 @@ const useCoreTabbarStore = defineStore('core-tabbar', { */ async _bulkCloseByPaths(paths: string[]) { this.tabs = this.tabs.filter((item) => { - return !paths.includes(this.getTabPath(item)); + return !paths.includes(getTabPath(item)); }); this.updateCacheTab(); @@ -128,12 +83,12 @@ const useCoreTabbarStore = defineStore('core-tabbar', { */ addTab(routeTab: TabItem) { const tab = cloneTab(routeTab); - if (!isTabShow(tab)) { + if (!isTabShown(tab)) { return; } const tabIndex = this.tabs.findIndex((tab) => { - return this.getTabPath(tab) === this.getTabPath(routeTab); + return getTabPath(tab) === getTabPath(routeTab); }); if (tabIndex === -1) { @@ -159,19 +114,22 @@ const useCoreTabbarStore = defineStore('core-tabbar', { */ async closeLeftTabs(tab: TabItem) { const index = this.tabs.findIndex( - (item) => this.getTabPath(item) === this.getTabPath(tab), + (item) => getTabPath(item) === getTabPath(tab), ); - if (index > 0) { - const leftTabs = this.tabs.slice(0, index); - const paths: string[] = []; - for (const item of leftTabs) { - if (!isAffixTab(tab)) { - paths.push(this.getTabPath(item)); - } - } - await this._bulkCloseByPaths(paths); + if (index < 1) { + return; } + + const leftTabs = this.tabs.slice(0, index); + const paths: string[] = []; + + for (const item of leftTabs) { + if (!isAffixTab(item)) { + paths.push(getTabPath(item)); + } + } + await this._bulkCloseByPaths(paths); }, /** @@ -179,20 +137,18 @@ const useCoreTabbarStore = defineStore('core-tabbar', { * @param tab */ async closeOtherTabs(tab: TabItem) { - const closePaths = this.tabs.map((item) => this.getTabPath(item)); + const closePaths = this.tabs.map((item) => getTabPath(item)); const paths: string[] = []; for (const path of closePaths) { if (path !== tab.fullPath) { - const closeTab = this.tabs.find( - (item) => this.getTabPath(item) === path, - ); + const closeTab = this.tabs.find((item) => getTabPath(item) === path); if (!closeTab) { continue; } - if (!isAffixTab(tab)) { - paths.push(this.getTabPath(closeTab)); + if (!isAffixTab(closeTab)) { + paths.push(getTabPath(closeTab)); } } } @@ -205,7 +161,7 @@ const useCoreTabbarStore = defineStore('core-tabbar', { */ async closeRightTabs(tab: TabItem) { const index = this.tabs.findIndex( - (item) => this.getTabPath(item) === this.getTabPath(tab), + (item) => getTabPath(item) === getTabPath(tab), ); if (index >= 0 && index < this.tabs.length - 1) { @@ -213,8 +169,8 @@ const useCoreTabbarStore = defineStore('core-tabbar', { const paths: string[] = []; for (const item of rightTabs) { - if (!isAffixTab(tab)) { - paths.push(this.getTabPath(item)); + if (!isAffixTab(item)) { + paths.push(getTabPath(item)); } } await this._bulkCloseByPaths(paths); @@ -230,13 +186,13 @@ const useCoreTabbarStore = defineStore('core-tabbar', { const { currentRoute } = router; // 关闭不是激活选项卡 - if (this.getTabPath(currentRoute.value) !== this.getTabPath(tab)) { + if (getTabPath(currentRoute.value) !== getTabPath(tab)) { this._close(tab); this.updateCacheTab(); return; } const index = this.getTabs.findIndex( - (item) => this.getTabPath(item) === this.getTabPath(currentRoute.value), + (item) => getTabPath(item) === getTabPath(currentRoute.value), ); const before = this.getTabs[index - 1]; @@ -259,25 +215,21 @@ const useCoreTabbarStore = defineStore('core-tabbar', { * @param key */ async closeTabByKey(key: string, router: Router) { - const index = this.tabs.findIndex( - (item) => this.getTabPath(item) === key, - ); + const index = this.tabs.findIndex((item) => getTabPath(item) === key); if (index === -1) { return; } await this.closeTab(this.tabs[index], router); }, - getTabPath(tab: RouteRecordNormalized | TabItem) { - return decodeURIComponent((tab as TabItem).fullPath || tab.path); - }, + /** * @zh_CN 固定标签页 * @param tab */ - async pushPinTab(tab: TabItem) { + async pinTab(tab: TabItem) { const index = this.tabs.findIndex( - (item) => this.getTabPath(item) === this.getTabPath(tab), + (item) => getTabPath(item) === getTabPath(tab), ); if (index !== -1) { tab.meta.affixTab = true; @@ -291,13 +243,13 @@ const useCoreTabbarStore = defineStore('core-tabbar', { const { currentRoute } = router; const { name } = currentRoute.value; - this.excludeCacheTabs.add(name as string); + this.excludeCachedTabs.add(name as string); this.renderRouteView = false; startProgress(); await new Promise((resolve) => setTimeout(resolve, 200)); - this.excludeCacheTabs.delete(name as string); + this.excludeCachedTabs.delete(name as string); this.renderRouteView = true; stopProgress(); }, @@ -315,9 +267,9 @@ const useCoreTabbarStore = defineStore('core-tabbar', { * @zh_CN 取消固定标签页 * @param tab */ - async unPushPinTab(tab: TabItem) { + async unpinTab(tab: TabItem) { const index = this.tabs.findIndex( - (item) => this.getTabPath(item) === this.getTabPath(tab), + (item) => getTabPath(item) === getTabPath(tab), ); if (index !== -1) { @@ -347,33 +299,32 @@ const useCoreTabbarStore = defineStore('core-tabbar', { const name = tab.name as string; cacheMap.add(name); } - this.cacheTabs = cacheMap; + this.cachedTabs = cacheMap; }, }, getters: { affixTabs(): TabItem[] { return this.tabs.filter((tab) => isAffixTab(tab)); }, - getCacheTabs(): string[] { - return [...this.cacheTabs]; + getCachedTabs(): string[] { + return [...this.cachedTabs]; }, - getExcludeTabs(): string[] { - return [...this.excludeCacheTabs]; + getExcludeCachedTabs(): string[] { + return [...this.excludeCachedTabs]; }, getTabs(): TabItem[] { const affixTabs = this.tabs.filter((tab) => isAffixTab(tab)); const normalTabs = this.tabs.filter((tab) => !isAffixTab(tab)); - return [...affixTabs, ...normalTabs]; }, }, persist: { // 持久化 - paths: [], + paths: ['tabs'], }, state: (): TabsState => ({ - cacheTabs: new Set(), - excludeCacheTabs: new Set(), + cachedTabs: new Set(), + excludeCachedTabs: new Set(), renderRouteView: true, tabs: [], }), @@ -385,4 +336,57 @@ if (hot) { hot.accept(acceptHMRUpdate(useCoreTabbarStore, hot)); } +/** + * @zh_CN 克隆路由,防止路由被修改 + * @param route + */ +function cloneTab(route: TabItem): TabItem { + if (!route) { + return route; + } + const { matched, ...opt } = route; + return { + ...opt, + matched: (matched + ? matched.map((item) => ({ + meta: item.meta, + name: item.name, + path: item.path, + })) + : undefined) as RouteRecordNormalized[], + }; +} + +/** + * @zh_CN 是否是固定标签页 + * @param tab + */ +function isAffixTab(tab: TabItem) { + return tab.meta?.affixTab ?? false; +} + +/** + * @zh_CN 是否显示标签 + * @param tab + */ +function isTabShown(tab: TabItem) { + return !tab.meta.hideInTab; +} + +/** + * @zh_CN 获取标签页路径 + * @param tab + */ +function getTabPath(tab: RouteRecordNormalized | TabItem) { + return decodeURIComponent((tab as TabItem).fullPath || tab.path); +} + +function routeToTab(route: RouteRecordNormalized) { + return { + meta: route.meta, + name: route.name, + path: route.path, + } as TabItem; +} + export { useCoreTabbarStore }; diff --git a/packages/@core/forward/stores/src/setup.ts b/packages/@core/forward/stores/src/setup.ts index 84d69355..5efc37ab 100644 --- a/packages/@core/forward/stores/src/setup.ts +++ b/packages/@core/forward/stores/src/setup.ts @@ -2,8 +2,7 @@ import { createPinia } from 'pinia'; interface InitStoreOptions { /** - * @zh_CN 应用名,由于 @vben-core/stores 是公用的,后续可能有多个app,为了防止多个app缓存冲突,可在这里配置应用名 - * 应用名将被用于持久化的前缀 + * @zh_CN 应用名,由于 @vben-core/stores 是公用的,后续可能有多个app,为了防止多个app缓存冲突,可在这里配置应用名,应用名将被用于持久化的前缀 */ namespace: string; } diff --git a/packages/@core/locales/src/langs/en-US.json b/packages/@core/locales/src/langs/en-US.json index 43861ae0..354c0160 100644 --- a/packages/@core/locales/src/langs/en-US.json +++ b/packages/@core/locales/src/langs/en-US.json @@ -159,6 +159,7 @@ "title": "Tabbar", "enable": "Enable Tab Bar", "icon": "Display Tabbar Icon", + "persist": "Persistent tabs", "context-menu": { "reload": "Reload", "close": "Close", diff --git a/packages/@core/locales/src/langs/zh-CN.json b/packages/@core/locales/src/langs/zh-CN.json index b4a8bac2..c06b6d98 100644 --- a/packages/@core/locales/src/langs/zh-CN.json +++ b/packages/@core/locales/src/langs/zh-CN.json @@ -158,6 +158,7 @@ "title": "标签栏", "enable": "启用标签栏", "icon": "显示标签栏图标", + "persist": "持久化标签页", "context-menu": { "reload": "重新加载", "close": "关闭标签页", diff --git a/packages/@core/ui-kit/tabs-ui/src/components/chrome-tabs/tab.vue b/packages/@core/ui-kit/tabs-ui/src/components/chrome-tabs/tab.vue index 96bf2e15..6a4a0d80 100644 --- a/packages/@core/ui-kit/tabs-ui/src/components/chrome-tabs/tab.vue +++ b/packages/@core/ui-kit/tabs-ui/src/components/chrome-tabs/tab.vue @@ -25,15 +25,15 @@ defineOptions({ withDefaults(defineProps(), { icon: '', }); -const emit = defineEmits<{ close: []; unPushPin: [] }>(); +const emit = defineEmits<{ close: []; unpinTab: [] }>(); const { b, e, is } = useNamespace('chrome-tab'); function handleClose() { emit('close'); } -function handleUnPushPin() { - emit('unPushPin'); +function handleUnpinTab() { + emit('unpinTab'); } @@ -66,7 +66,7 @@ function handleUnPushPin() {
diff --git a/packages/@core/ui-kit/tabs-ui/src/components/chrome-tabs/tabs.vue b/packages/@core/ui-kit/tabs-ui/src/components/chrome-tabs/tabs.vue index 1ab3ddfd..7fe48b9f 100644 --- a/packages/@core/ui-kit/tabs-ui/src/components/chrome-tabs/tabs.vue +++ b/packages/@core/ui-kit/tabs-ui/src/components/chrome-tabs/tabs.vue @@ -22,7 +22,7 @@ const props = withDefaults(defineProps(), { tabs: () => [], }); -const emit = defineEmits<{ close: [string]; unPushPin: [TabItem] }>(); +const emit = defineEmits<{ close: [string]; unpinTab: [TabItem] }>(); const gap = 7; @@ -77,8 +77,8 @@ onMounted(() => { function handleClose(key: string) { emit('close', key); } -function handleUnPushPin(tab: TabItem) { - emit('unPushPin', tab); +function handleUnpinTab(tab: TabItem) { + emit('unpinTab', tab); } @@ -103,7 +103,7 @@ function handleUnPushPin(tab: TabItem) { :title="tab.title" @click="active = tab.key" @close="() => handleClose(tab.key)" - @un-push-pin="() => handleUnPushPin(tab)" + @unpin-tab="() => handleUnpinTab(tab)" /> diff --git a/packages/business/access/src/use-access.ts b/packages/business/access/src/use-access.ts index fc006183..734233e6 100644 --- a/packages/business/access/src/use-access.ts +++ b/packages/business/access/src/use-access.ts @@ -15,7 +15,7 @@ function useAccess() { * @param roles */ function hasAuthByRoles(roles: string[]) { - const userRoleSet = new Set(coreAccessStore.getUserRoles); + const userRoleSet = new Set(coreAccessStore.userRoles); const intersection = roles.filter((item) => userRoleSet.has(item)); return intersection.length > 0; } @@ -26,7 +26,7 @@ function useAccess() { * @param codes */ function hasAuthByCodes(codes: string[]) { - const userCodesSet = new Set(coreAccessStore.getAccessCodes); + const userCodesSet = new Set(coreAccessStore.accessCodes); const intersection = codes.filter((item) => userCodesSet.has(item)); return intersection.length > 0; diff --git a/packages/business/layouts/src/basic/content/content.vue b/packages/business/layouts/src/basic/content/content.vue index c7ee22e5..f0298286 100644 --- a/packages/business/layouts/src/basic/content/content.vue +++ b/packages/business/layouts/src/basic/content/content.vue @@ -10,12 +10,12 @@ import { useContentSpinner } from './use-content-spinner'; defineOptions({ name: 'LayoutContent' }); -const tabsStore = useCoreTabbarStore(); +const tabbarStore = useCoreTabbarStore(); const { keepAlive } = usePreferences(); const { spinning } = useContentSpinner(); -const { getCacheTabs, getExcludeTabs, renderRouteView } = - storeToRefs(tabsStore); +const { getCachedTabs, getExcludeCachedTabs, renderRouteView } = + storeToRefs(tabbarStore); // 页面切换动画 function getTransitionName(route: RouteLocationNormalizedLoaded) { @@ -36,7 +36,7 @@ function getTransitionName(route: RouteLocationNormalizedLoaded) { // return; // } // 已经打开且已经加载过的页面不使用动画 - const inTabs = getCacheTabs.value.includes(route.name as string); + const inTabs = getCachedTabs.value.includes(route.name as string); return inTabs && route.meta.loaded ? undefined : transitionName; } @@ -54,8 +54,8 @@ function getTransitionName(route: RouteLocationNormalizedLoaded) { diff --git a/packages/business/layouts/src/basic/menu/use-extra-menu.ts b/packages/business/layouts/src/basic/menu/use-extra-menu.ts index 0d15ffbf..26b3193c 100644 --- a/packages/business/layouts/src/basic/menu/use-extra-menu.ts +++ b/packages/business/layouts/src/basic/menu/use-extra-menu.ts @@ -13,7 +13,7 @@ function useExtraMenu() { const accessStore = useCoreAccessStore(); const { navigation } = useNavigation(); - const menus = computed(() => accessStore.getAccessMenus); + const menus = computed(() => accessStore.accessMenus); const route = useRoute(); const extraMenus = ref([]); diff --git a/packages/business/layouts/src/basic/menu/use-mixed-menu.ts b/packages/business/layouts/src/basic/menu/use-mixed-menu.ts index 8188ab4b..ccf0b841 100644 --- a/packages/business/layouts/src/basic/menu/use-mixed-menu.ts +++ b/packages/business/layouts/src/basic/menu/use-mixed-menu.ts @@ -29,7 +29,7 @@ function useMixedMenu() { } return enableSidebar; }); - const menus = computed(() => accessStore.getAccessMenus); + const menus = computed(() => accessStore.accessMenus); /** * 头部菜单 diff --git a/packages/business/layouts/src/basic/tabbar/tabbar.vue b/packages/business/layouts/src/basic/tabbar/tabbar.vue index ceea9699..54a5e783 100644 --- a/packages/business/layouts/src/basic/tabbar/tabbar.vue +++ b/packages/business/layouts/src/basic/tabbar/tabbar.vue @@ -1,4 +1,8 @@ diff --git a/packages/business/layouts/src/basic/tabbar/use-tabs.ts b/packages/business/layouts/src/basic/tabbar/use-tabs.ts index b775421b..38c89dbb 100644 --- a/packages/business/layouts/src/basic/tabbar/use-tabs.ts +++ b/packages/business/layouts/src/basic/tabbar/use-tabs.ts @@ -30,7 +30,7 @@ function useTabs() { const router = useRouter(); const route = useRoute(); const accessStore = useCoreAccessStore(); - const tabbarStore = useCoreTabbarStore(); + const coreTabbarStore = useCoreTabbarStore(); const { accessMenus } = storeToRefs(accessStore); const currentActive = computed(() => { @@ -39,7 +39,7 @@ function useTabs() { const { locale } = useI18n(); const currentTabs = ref(); - watch([() => tabbarStore.getTabs, () => locale.value], ([tabs, _]) => { + watch([() => coreTabbarStore.getTabs, () => locale.value], ([tabs, _]) => { currentTabs.value = tabs.map((item) => wrapperTabLocale(item)); }); @@ -50,7 +50,7 @@ function useTabs() { const affixTabs = filterTree(router.getRoutes(), (route) => { return !!route.meta?.affixTab; }); - tabbarStore.setAffixTabs(affixTabs); + coreTabbarStore.setAffixTabs(affixTabs); }; // 点击tab,跳转路由 @@ -60,7 +60,7 @@ function useTabs() { // 关闭tab const handleClose = async (key: string) => { - await tabbarStore.closeTabByKey(key, router); + await coreTabbarStore.closeTabByKey(key, router); }; function wrapperTabLocale(tab: RouteLocationNormalizedGeneric) { @@ -84,14 +84,14 @@ function useTabs() { watch( () => route.path, () => { - tabbarStore.addTab(route as RouteLocationNormalized); + coreTabbarStore.addTab(route as RouteLocationNormalized); }, { immediate: true }, ); const createContextMenus = (tab: TabItem) => { - const tabs = tabbarStore.getTabs; - const affixTabs = tabbarStore.affixTabs; + const tabs = coreTabbarStore.getTabs; + const affixTabs = coreTabbarStore.affixTabs; const index = tabs.findIndex((item) => item.path === tab.path); const disabled = tabs.length <= 1; @@ -113,7 +113,7 @@ function useTabs() { { disabled: !isCurrentTab, handler: async () => { - await tabbarStore.refresh(router); + await coreTabbarStore.refresh(router); }, icon: IcRoundRefresh, key: 'reload', @@ -122,7 +122,7 @@ function useTabs() { { disabled: !!affixTab || disabled, handler: async () => { - await tabbarStore.closeTab(tab, router); + await coreTabbarStore.closeTab(tab, router); }, icon: IcRoundClose, key: 'close', @@ -131,8 +131,8 @@ function useTabs() { { handler: async () => { await (affixTab - ? tabbarStore.unPushPinTab(tab) - : tabbarStore.pushPinTab(tab)); + ? coreTabbarStore.unpinTab(tab) + : coreTabbarStore.pinTab(tab)); }, icon: affixTab ? MdiPinOff : MdiPin, key: 'affix', @@ -144,7 +144,7 @@ function useTabs() { { disabled: closeLeftDisabled, handler: async () => { - await tabbarStore.closeLeftTabs(tab); + await coreTabbarStore.closeLeftTabs(tab); }, icon: MdiFormatHorizontalAlignLeft, key: 'close-left', @@ -153,7 +153,7 @@ function useTabs() { { disabled: closeRightDisabled, handler: async () => { - await tabbarStore.closeRightTabs(tab); + await coreTabbarStore.closeRightTabs(tab); }, icon: MdiFormatHorizontalAlignRight, key: 'close-right', @@ -163,7 +163,7 @@ function useTabs() { { disabled: closeOtherDisabled, handler: async () => { - await tabbarStore.closeOtherTabs(tab); + await coreTabbarStore.closeOtherTabs(tab); }, icon: MdiArrowExpandHorizontal, key: 'close-other', @@ -172,7 +172,7 @@ function useTabs() { { disabled, handler: async () => { - await tabbarStore.closeAllTabs(router); + await coreTabbarStore.closeAllTabs(router); }, icon: IcRoundMultipleStop, key: 'close-all', @@ -190,8 +190,8 @@ function useTabs() { /** * 取消固定标签页 */ - const handleUnPushPin = async (tab: TabItem) => { - await tabbarStore.unPushPinTab(tab); + const handleUnpinTab = async (tab: TabItem) => { + await coreTabbarStore.unpinTab(tab); }; return { @@ -200,7 +200,7 @@ function useTabs() { currentTabs, handleClick, handleClose, - handleUnPushPin, + handleUnpinTab, }; } diff --git a/packages/business/layouts/src/iframe/iframe-router-view.vue b/packages/business/layouts/src/iframe/iframe-router-view.vue index 55b36c0a..358a84f3 100644 --- a/packages/business/layouts/src/iframe/iframe-router-view.vue +++ b/packages/business/layouts/src/iframe/iframe-router-view.vue @@ -11,7 +11,7 @@ import { useCoreTabbarStore } from '@vben-core/stores'; defineOptions({ name: 'IFrameRouterView' }); const spinningList = ref([]); -const tabsStore = useCoreTabbarStore(); +const coreTabbarStore = useCoreTabbarStore(); const route = useRoute(); const enableTabbar = computed(() => preferences.tabbar.enable); @@ -20,7 +20,7 @@ const iframeRoutes = computed(() => { if (!enableTabbar.value) { return route.meta.iframeSrc ? [route] : []; } - return tabsStore.getTabs.filter((tab) => !!tab.meta?.iframeSrc); + return coreTabbarStore.getTabs.filter((tab) => !!tab.meta?.iframeSrc); }); const tabNames = computed( @@ -36,7 +36,7 @@ function routeShow(tabItem: RouteLocationNormalized) { function canRender(tabItem: RouteLocationNormalized) { const { meta, name } = tabItem; - if (!name || !tabsStore.renderRouteView) { + if (!name || !coreTabbarStore.renderRouteView) { return false; } @@ -52,7 +52,7 @@ function canRender(tabItem: RouteLocationNormalized) { ) { return false; } - return tabsStore.getTabs.some((tab) => tab.name === name); + return coreTabbarStore.getTabs.some((tab) => tab.name === name); } function hideLoading(index: number) { diff --git a/packages/business/layouts/src/widgets/preferences/blocks/layout/tabbar.vue b/packages/business/layouts/src/widgets/preferences/blocks/layout/tabbar.vue index be327eb9..b17773fb 100644 --- a/packages/business/layouts/src/widgets/preferences/blocks/layout/tabbar.vue +++ b/packages/business/layouts/src/widgets/preferences/blocks/layout/tabbar.vue @@ -11,6 +11,7 @@ defineProps<{ disabled?: boolean }>(); const tabbarEnable = defineModel('tabbarEnable'); const tabbarShowIcon = defineModel('tabbarShowIcon'); +const tabbarPersist = defineModel('tabbarPersist'); diff --git a/packages/business/layouts/src/widgets/preferences/preferences-sheet.vue b/packages/business/layouts/src/widgets/preferences/preferences-sheet.vue index 93dcd216..7891181a 100644 --- a/packages/business/layouts/src/widgets/preferences/preferences-sheet.vue +++ b/packages/business/layouts/src/widgets/preferences/preferences-sheet.vue @@ -96,6 +96,7 @@ const breadcrumbHideOnlyOne = defineModel('breadcrumbHideOnlyOne'); const tabbarEnable = defineModel('tabbarEnable'); const tabbarShowIcon = defineModel('tabbarShowIcon'); +const tabbarPersist = defineModel('tabbarPersist'); const navigationStyleType = defineModel( 'navigationStyleType', @@ -341,6 +342,7 @@ async function handleReset() {