提交 967b28c4 作者: Vben

feat: persistent save tab, fix #359

上级 2037293a
...@@ -13,6 +13,10 @@ ...@@ -13,6 +13,10 @@
- 移除 `useDebounceFn` 使用`vueuse`-`useDebounceFn`代替 - 移除 `useDebounceFn` 使用`vueuse`-`useDebounceFn`代替
- 移除 `useThrottle` 使用`vueuse`-`useThrottleFn`代替 - 移除 `useThrottle` 使用`vueuse`-`useThrottleFn`代替
### ✨ Features
- 标签页支持持久化保存
### ✨ Refactor ### ✨ Refactor
- 移除 `useElResize` - 移除 `useElResize`
......
...@@ -40,7 +40,7 @@ export function configThemePlugin(isBuild: boolean): Plugin[] { ...@@ -40,7 +40,7 @@ export function configThemePlugin(isBuild: boolean): Plugin[] {
// black: '#0e1117', // black: '#0e1117',
// #8b949e // #8b949e
'text-color-secondary': '#8b949e', 'text-color-secondary': '#8b949e',
// 'border-color-base': '#30363d', 'border-color-base': '#303030',
// 'border-color-split': '#30363d', // 'border-color-split': '#30363d',
'item-active-bg': '#111b26', 'item-active-bg': '#111b26',
}, },
......
<template> <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> <slot name="headerTitle" v-if="$slots.headerTitle"></slot>
<BasicTitle :helpMessage="helpMessage" v-if="!$slots.headerTitle && title"> <BasicTitle :helpMessage="helpMessage" v-if="!$slots.headerTitle && title">
{{ title }} {{ title }}
...@@ -138,3 +138,8 @@ ...@@ -138,3 +138,8 @@
}, },
}); });
</script> </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__'; ...@@ -15,6 +15,8 @@ export const PROJ_CFG_KEY = 'PROJ__CFG__KEY__';
// lock info // lock info
export const LOCK_INFO_KEY = 'LOCK__INFO__KEY__'; 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__'; export const APP_DARK_MODE_KEY_ = '__APP__DARK__MODE__';
// base global local key // base global local key
......
...@@ -10,7 +10,7 @@ const page: AppRouteModule = { ...@@ -10,7 +10,7 @@ const page: AppRouteModule = {
path: '/page-demo', path: '/page-demo',
name: 'PageDemo', name: 'PageDemo',
component: LAYOUT, component: LAYOUT,
redirect: '/page-demo/exception', redirect: '/page-demo/form/basic',
meta: { meta: {
icon: 'ion:aperture-outline', icon: 'ion:aperture-outline',
title: t('routes.demo.page.page'), title: t('routes.demo.page.page'),
......
...@@ -114,13 +114,13 @@ const setting: ProjectConfig = { ...@@ -114,13 +114,13 @@ const setting: ProjectConfig = {
// Multi-label // Multi-label
multiTabsSetting: { multiTabsSetting: {
cache: false,
// Turn on // Turn on
show: true, show: true,
// Is it possible to drag and drop sorting tabs // Is it possible to drag and drop sorting tabs
canDrag: true, canDrag: true,
// Turn on quick actions // Turn on quick actions
showQuick: true, showQuick: true,
// Whether to show the refresh button // Whether to show the refresh button
showRedo: true, showRedo: true,
// Whether to show the collapse button // Whether to show the collapse button
......
...@@ -12,7 +12,7 @@ import { resetRouter } from '/@/router'; ...@@ -12,7 +12,7 @@ import { resetRouter } from '/@/router';
import { deepMerge } from '/@/utils'; import { deepMerge } from '/@/utils';
interface AppState { interface AppState {
darkMode: ThemeEnum; darkMode?: ThemeEnum;
// Page loading status // Page loading status
pageLoading: boolean; pageLoading: boolean;
// project config // project config
...@@ -24,7 +24,7 @@ let timeId: TimeoutHandle; ...@@ -24,7 +24,7 @@ let timeId: TimeoutHandle;
export const useAppStore = defineStore({ export const useAppStore = defineStore({
id: 'app', id: 'app',
state: (): AppState => ({ state: (): AppState => ({
darkMode: ThemeEnum.LIGHT, darkMode: undefined,
pageLoading: false, pageLoading: false,
projectConfig: Persistent.getLocal(PROJ_CFG_KEY), projectConfig: Persistent.getLocal(PROJ_CFG_KEY),
beforeMiniInfo: {}, beforeMiniInfo: {},
......
...@@ -5,10 +5,14 @@ import { defineStore } from 'pinia'; ...@@ -5,10 +5,14 @@ import { defineStore } from 'pinia';
import { store } from '/@/store'; import { store } from '/@/store';
import { useGo, useRedo } from '/@/hooks/web/usePage'; import { useGo, useRedo } from '/@/hooks/web/usePage';
import { Persistent } from '/@/utils/cache/persistent';
import { PageEnum } from '/@/enums/pageEnum'; import { PageEnum } from '/@/enums/pageEnum';
import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/routes/basic'; import { PAGE_NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '/@/router/routes/basic';
import { getRawRoute } from '/@/utils'; import { getRawRoute } from '/@/utils';
import { MULTIPLE_TABS_KEY } from '/@/enums/cacheEnum';
import projectSetting from '/@/settings/projectSetting';
export interface MultipleTabState { export interface MultipleTabState {
cacheTabList: Set<string>; cacheTabList: Set<string>;
...@@ -21,13 +25,15 @@ function handleGotoPage(router: Router) { ...@@ -21,13 +25,15 @@ function handleGotoPage(router: Router) {
go(unref(router.currentRoute).path, true); go(unref(router.currentRoute).path, true);
} }
const cacheTab = projectSetting.multiTabsSetting.cache;
export const useMultipleTabStore = defineStore({ export const useMultipleTabStore = defineStore({
id: 'app-multiple-tab', id: 'app-multiple-tab',
state: (): MultipleTabState => ({ state: (): MultipleTabState => ({
// Tabs that need to be cached // Tabs that need to be cached
cacheTabList: new Set(), cacheTabList: new Set(),
// multiple tab list // multiple tab list
tabList: [], tabList: cacheTab ? Persistent.getLocal(MULTIPLE_TABS_KEY) || [] : [],
// Index of the last moved tab // Index of the last moved tab
lastDragEndIndex: 0, lastDragEndIndex: 0,
}), }),
...@@ -135,6 +141,7 @@ export const useMultipleTabStore = defineStore({ ...@@ -135,6 +141,7 @@ export const useMultipleTabStore = defineStore({
// Add tab // Add tab
this.tabList.push(route); this.tabList.push(route);
this.updateCacheTab(); this.updateCacheTab();
cacheTab && Persistent.setLocal(MULTIPLE_TABS_KEY, this.tabList);
}, },
async closeTab(tab: RouteLocationNormalized, router: Router) { async closeTab(tab: RouteLocationNormalized, router: Router) {
......
import type { LockInfo, UserInfo } from '/#/store'; import type { LockInfo, UserInfo } from '/#/store';
import type { ProjectConfig } from '/#/config'; import type { ProjectConfig } from '/#/config';
import type { RouteLocationNormalized } from 'vue-router';
import { createLocalStorage, createSessionStorage } from '/@/utils/cache'; import { createLocalStorage, createSessionStorage } from '/@/utils/cache';
import { Memory } from './memory'; import { Memory } from './memory';
...@@ -11,6 +12,7 @@ import { ...@@ -11,6 +12,7 @@ import {
PROJ_CFG_KEY, PROJ_CFG_KEY,
APP_LOCAL_CACHE_KEY, APP_LOCAL_CACHE_KEY,
APP_SESSION_CACHE_KEY, APP_SESSION_CACHE_KEY,
MULTIPLE_TABS_KEY,
} from '/@/enums/cacheEnum'; } from '/@/enums/cacheEnum';
import { DEFAULT_CACHE_TIME } from '/@/settings/encryptionSetting'; import { DEFAULT_CACHE_TIME } from '/@/settings/encryptionSetting';
import { toRaw } from 'vue'; import { toRaw } from 'vue';
...@@ -21,6 +23,7 @@ interface BasicStore { ...@@ -21,6 +23,7 @@ interface BasicStore {
[ROLES_KEY]: string[]; [ROLES_KEY]: string[];
[LOCK_INFO_KEY]: LockInfo; [LOCK_INFO_KEY]: LockInfo;
[PROJ_CFG_KEY]: ProjectConfig; [PROJ_CFG_KEY]: ProjectConfig;
[MULTIPLE_TABS_KEY]: RouteLocationNormalized[];
} }
type LocalStore = BasicStore; type LocalStore = BasicStore;
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
<div class="max-h-80 overflow-auto"> <div class="max-h-80 overflow-auto">
<ul> <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"> <div class="flex items-center">
<span class="mr-2 text-primary font-medium">收到消息:</span> <span class="mr-2 text-primary font-medium">收到消息:</span>
<span>{{ formatToDateTime(item.time) }}</span> <span>{{ formatToDateTime(item.time) }}</span>
......
...@@ -33,6 +33,7 @@ export interface MenuSetting { ...@@ -33,6 +33,7 @@ export interface MenuSetting {
} }
export interface MultiTabsSetting { export interface MultiTabsSetting {
cache: boolean;
show: boolean; show: boolean;
showQuick: boolean; showQuick: boolean;
canDrag: boolean; canDrag: boolean;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论