mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-27 06:40:51 +08:00
feat: persistent save tab, fix #359
This commit is contained in:
@@ -13,6 +13,10 @@
|
||||
- 移除 `useDebounceFn` 使用`vueuse`-`useDebounceFn`代替
|
||||
- 移除 `useThrottle` 使用`vueuse`-`useThrottleFn`代替
|
||||
|
||||
### ✨ Features
|
||||
|
||||
- 标签页支持持久化保存
|
||||
|
||||
### ✨ Refactor
|
||||
|
||||
- 移除 `useElResize`
|
||||
|
@@ -40,7 +40,7 @@ export function configThemePlugin(isBuild: boolean): Plugin[] {
|
||||
// black: '#0e1117',
|
||||
// #8b949e
|
||||
'text-color-secondary': '#8b949e',
|
||||
// 'border-color-base': '#30363d',
|
||||
'border-color-base': '#303030',
|
||||
// 'border-color-split': '#30363d',
|
||||
'item-active-bg': '#111b26',
|
||||
},
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="flex px-2 py-1.5 items-center border-b-1">
|
||||
<div class="flex px-2 py-1.5 items-center basic-tree-header">
|
||||
<slot name="headerTitle" v-if="$slots.headerTitle"></slot>
|
||||
<BasicTitle :helpMessage="helpMessage" v-if="!$slots.headerTitle && title">
|
||||
{{ title }}
|
||||
@@ -138,3 +138,8 @@
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.basic-tree-header {
|
||||
border-bottom: 1px solid @border-color-base;
|
||||
}
|
||||
</style>
|
||||
|
@@ -15,6 +15,8 @@ export const PROJ_CFG_KEY = 'PROJ__CFG__KEY__';
|
||||
// lock info
|
||||
export const LOCK_INFO_KEY = 'LOCK__INFO__KEY__';
|
||||
|
||||
export const MULTIPLE_TABS_KEY = 'MULTIPLE_TABS__KEY__';
|
||||
|
||||
export const APP_DARK_MODE_KEY_ = '__APP__DARK__MODE__';
|
||||
|
||||
// base global local key
|
||||
|
@@ -10,7 +10,7 @@ const page: AppRouteModule = {
|
||||
path: '/page-demo',
|
||||
name: 'PageDemo',
|
||||
component: LAYOUT,
|
||||
redirect: '/page-demo/exception',
|
||||
redirect: '/page-demo/form/basic',
|
||||
meta: {
|
||||
icon: 'ion:aperture-outline',
|
||||
title: t('routes.demo.page.page'),
|
||||
|
@@ -114,13 +114,13 @@ const setting: ProjectConfig = {
|
||||
|
||||
// Multi-label
|
||||
multiTabsSetting: {
|
||||
cache: false,
|
||||
// Turn on
|
||||
show: true,
|
||||
// Is it possible to drag and drop sorting tabs
|
||||
canDrag: true,
|
||||
// Turn on quick actions
|
||||
showQuick: true,
|
||||
|
||||
// Whether to show the refresh button
|
||||
showRedo: true,
|
||||
// Whether to show the collapse button
|
||||
|
@@ -12,7 +12,7 @@ import { resetRouter } from '/@/router';
|
||||
import { deepMerge } from '/@/utils';
|
||||
|
||||
interface AppState {
|
||||
darkMode: ThemeEnum;
|
||||
darkMode?: ThemeEnum;
|
||||
// Page loading status
|
||||
pageLoading: boolean;
|
||||
// project config
|
||||
@@ -24,7 +24,7 @@ let timeId: TimeoutHandle;
|
||||
export const useAppStore = defineStore({
|
||||
id: 'app',
|
||||
state: (): AppState => ({
|
||||
darkMode: ThemeEnum.LIGHT,
|
||||
darkMode: undefined,
|
||||
pageLoading: false,
|
||||
projectConfig: Persistent.getLocal(PROJ_CFG_KEY),
|
||||
beforeMiniInfo: {},
|
||||
|
@@ -5,10 +5,14 @@ import { defineStore } from 'pinia';
|
||||
import { store } from '/@/store';
|
||||
|
||||
import { useGo, useRedo } from '/@/hooks/web/usePage';
|
||||
import { Persistent } from '/@/utils/cache/persistent';
|
||||
|
||||
import { PageEnum } from '/@/enums/pageEnum';
|
||||
import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/routes/basic';
|
||||
import { getRawRoute } from '/@/utils';
|
||||
import { MULTIPLE_TABS_KEY } from '/@/enums/cacheEnum';
|
||||
|
||||
import projectSetting from '/@/settings/projectSetting';
|
||||
|
||||
export interface MultipleTabState {
|
||||
cacheTabList: Set<string>;
|
||||
@@ -21,13 +25,15 @@ function handleGotoPage(router: Router) {
|
||||
go(unref(router.currentRoute).path, true);
|
||||
}
|
||||
|
||||
const cacheTab = projectSetting.multiTabsSetting.cache;
|
||||
|
||||
export const useMultipleTabStore = defineStore({
|
||||
id: 'app-multiple-tab',
|
||||
state: (): MultipleTabState => ({
|
||||
// Tabs that need to be cached
|
||||
cacheTabList: new Set(),
|
||||
// multiple tab list
|
||||
tabList: [],
|
||||
tabList: cacheTab ? Persistent.getLocal(MULTIPLE_TABS_KEY) || [] : [],
|
||||
// Index of the last moved tab
|
||||
lastDragEndIndex: 0,
|
||||
}),
|
||||
@@ -135,6 +141,7 @@ export const useMultipleTabStore = defineStore({
|
||||
// Add tab
|
||||
this.tabList.push(route);
|
||||
this.updateCacheTab();
|
||||
cacheTab && Persistent.setLocal(MULTIPLE_TABS_KEY, this.tabList);
|
||||
},
|
||||
|
||||
async closeTab(tab: RouteLocationNormalized, router: Router) {
|
||||
|
3
src/utils/cache/persistent.ts
vendored
3
src/utils/cache/persistent.ts
vendored
@@ -1,5 +1,6 @@
|
||||
import type { LockInfo, UserInfo } from '/#/store';
|
||||
import type { ProjectConfig } from '/#/config';
|
||||
import type { RouteLocationNormalized } from 'vue-router';
|
||||
|
||||
import { createLocalStorage, createSessionStorage } from '/@/utils/cache';
|
||||
import { Memory } from './memory';
|
||||
@@ -11,6 +12,7 @@ import {
|
||||
PROJ_CFG_KEY,
|
||||
APP_LOCAL_CACHE_KEY,
|
||||
APP_SESSION_CACHE_KEY,
|
||||
MULTIPLE_TABS_KEY,
|
||||
} from '/@/enums/cacheEnum';
|
||||
import { DEFAULT_CACHE_TIME } from '/@/settings/encryptionSetting';
|
||||
import { toRaw } from 'vue';
|
||||
@@ -21,6 +23,7 @@ interface BasicStore {
|
||||
[ROLES_KEY]: string[];
|
||||
[LOCK_INFO_KEY]: LockInfo;
|
||||
[PROJ_CFG_KEY]: ProjectConfig;
|
||||
[MULTIPLE_TABS_KEY]: RouteLocationNormalized[];
|
||||
}
|
||||
|
||||
type LocalStore = BasicStore;
|
||||
|
@@ -37,7 +37,7 @@
|
||||
|
||||
<div class="max-h-80 overflow-auto">
|
||||
<ul>
|
||||
<li v-for="item in getList" class="border-b-1 mt-2" :key="item.time">
|
||||
<li v-for="item in getList" class="mt-2" :key="item.time">
|
||||
<div class="flex items-center">
|
||||
<span class="mr-2 text-primary font-medium">收到消息:</span>
|
||||
<span>{{ formatToDateTime(item.time) }}</span>
|
||||
|
1
types/config.d.ts
vendored
1
types/config.d.ts
vendored
@@ -33,6 +33,7 @@ export interface MenuSetting {
|
||||
}
|
||||
|
||||
export interface MultiTabsSetting {
|
||||
cache: boolean;
|
||||
show: boolean;
|
||||
showQuick: boolean;
|
||||
canDrag: boolean;
|
||||
|
Reference in New Issue
Block a user