mirror of
https://github.com/m-xlsea/ruoyi-plus-soybean.git
synced 2025-09-24 07:49:47 +08:00
refactor(projects): 精简版+动态路由权限初步
This commit is contained in:
@ -1,9 +1,8 @@
|
||||
import type { App } from 'vue';
|
||||
import { createPinia } from 'pinia';
|
||||
|
||||
export const store = createPinia();
|
||||
|
||||
export function setupStore(app: App) {
|
||||
const store = createPinia();
|
||||
app.use(store);
|
||||
}
|
||||
|
||||
|
@ -1,45 +0,0 @@
|
||||
import type { RouteLocationNormalizedLoaded } from 'vue-router';
|
||||
import { ROUTE_HOME } from '@/router';
|
||||
import { brightenColor, darkenColor } from '@/utils';
|
||||
import type { MultiTabRoute } from '@/interface';
|
||||
|
||||
export function getHoverAndPressedColor(color: string) {
|
||||
return {
|
||||
hover: brightenColor(color),
|
||||
pressed: darkenColor(color)
|
||||
};
|
||||
}
|
||||
|
||||
/** 获取路由首页信息 */
|
||||
export function getHomeTabRoute(route: RouteLocationNormalizedLoaded) {
|
||||
const { name, path, meta } = ROUTE_HOME;
|
||||
const isHome = route.name === ROUTE_HOME.name;
|
||||
const home: MultiTabRoute = {
|
||||
name,
|
||||
path,
|
||||
fullPath: path,
|
||||
meta
|
||||
};
|
||||
if (isHome) {
|
||||
Object.assign(home, route);
|
||||
}
|
||||
return home;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取该页签在多页签数据中的索引
|
||||
* @param routes - 多页签数据
|
||||
* @param fullPath - 该页签的路径
|
||||
*/
|
||||
export function getIndexInTabRoutes(routes: MultiTabRoute[], fullPath: string) {
|
||||
return routes.findIndex(route => route.fullPath === fullPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断该页签是否在多页签数据中
|
||||
* @param routes - 多页签数据
|
||||
* @param fullPath - 该页签的路径
|
||||
*/
|
||||
export function isInTabRoutes(routes: MultiTabRoute[], fullPath: string) {
|
||||
return getIndexInTabRoutes(routes, fullPath) > -1;
|
||||
}
|
@ -1,203 +1,25 @@
|
||||
import { nextTick } from 'vue';
|
||||
import type { RouteLocationNormalizedLoaded } from 'vue-router';
|
||||
import type { ScrollbarInst } from 'naive-ui';
|
||||
import type { Ref } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import { router, ROUTE_HOME } from '@/router';
|
||||
import { store, useThemeStore } from '@/store';
|
||||
import { getTabRouteStorage } from '@/utils';
|
||||
import type { MultiTab, MultiTabRoute } from '@/interface';
|
||||
import { getHomeTabRoute, isInTabRoutes } from './helpers';
|
||||
import { useReload } from '@/hooks';
|
||||
|
||||
/** app状态 */
|
||||
interface AppState {
|
||||
layout: LayoutState;
|
||||
menu: MenuState;
|
||||
multiTab: MultiTab;
|
||||
/** 重新加载标记 */
|
||||
reloadFlag: boolean;
|
||||
settingDrawer: SettingDrawer;
|
||||
interface AppStore {
|
||||
/** 重载页面的标志 */
|
||||
reloadFlag: Ref<boolean>;
|
||||
/**
|
||||
* 触发重载页面
|
||||
* @param duration - 延迟时间(ms, 默认0)
|
||||
*/
|
||||
handleReload(duration?: number): void;
|
||||
}
|
||||
|
||||
/** 布局状态 */
|
||||
interface LayoutState {
|
||||
scrollbar: ScrollbarInst | null;
|
||||
}
|
||||
export const useAppStore = defineStore('app-store', () => {
|
||||
// 重新加载页面
|
||||
const { reloadFlag, handleReload } = useReload();
|
||||
|
||||
/** 菜单状态 */
|
||||
interface MenuState {
|
||||
/** 菜单折叠 */
|
||||
collapsed: boolean;
|
||||
/** 混合菜单vertical-mix是否固定二级菜单 */
|
||||
fixedMix: boolean;
|
||||
}
|
||||
const appStore: AppStore = {
|
||||
reloadFlag,
|
||||
handleReload
|
||||
};
|
||||
|
||||
/** 项目配置抽屉的状态 */
|
||||
interface SettingDrawer {
|
||||
/** 设置抽屉可见性 */
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
const appStore = defineStore({
|
||||
id: 'app-store',
|
||||
state: (): AppState => ({
|
||||
layout: {
|
||||
scrollbar: null
|
||||
},
|
||||
menu: {
|
||||
collapsed: false,
|
||||
fixedMix: false
|
||||
},
|
||||
multiTab: {
|
||||
routes: [],
|
||||
activeRoute: ''
|
||||
},
|
||||
reloadFlag: true,
|
||||
settingDrawer: {
|
||||
visible: false
|
||||
}
|
||||
}),
|
||||
getters: {
|
||||
activeMultiTabIndex(state) {
|
||||
const { routes, activeRoute } = state.multiTab;
|
||||
return routes.findIndex(v => v.fullPath === activeRoute);
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
/** 设置scrollbar的实例 */
|
||||
setScrollbarInstance(scrollbar: ScrollbarInst) {
|
||||
this.layout.scrollbar = scrollbar;
|
||||
},
|
||||
/** 重置滚动条行为 */
|
||||
resetScrollBehavior() {
|
||||
const { scrollbar } = this.layout;
|
||||
setTimeout(() => {
|
||||
scrollbar?.scrollTo({ left: 0, top: 0 });
|
||||
}, 250);
|
||||
},
|
||||
/** 折叠/展开菜单 */
|
||||
handleMenuCollapse(collapsed: boolean) {
|
||||
this.menu.collapsed = collapsed;
|
||||
},
|
||||
/** 设置混合菜单是否固定 */
|
||||
toggleFixedMixMenu() {
|
||||
this.menu.fixedMix = !this.menu.fixedMix;
|
||||
},
|
||||
/** 切换折叠/展开菜单 */
|
||||
toggleMenu() {
|
||||
this.menu.collapsed = !this.menu.collapsed;
|
||||
},
|
||||
/** 添加多页签的数据 */
|
||||
addMultiTab(route: RouteLocationNormalizedLoaded) {
|
||||
const { fullPath } = route;
|
||||
const isExist = isInTabRoutes(this.multiTab.routes, fullPath);
|
||||
if (!isExist) {
|
||||
this.multiTab.routes.push({ ...route });
|
||||
}
|
||||
},
|
||||
/** 删除多页签的数据 */
|
||||
removeMultiTab(fullPath: string) {
|
||||
const isActive = this.multiTab.activeRoute === fullPath;
|
||||
const { routes } = this.multiTab;
|
||||
const updateRoutes = routes.filter(v => v.fullPath !== fullPath);
|
||||
this.multiTab.routes = updateRoutes;
|
||||
if (isActive) {
|
||||
const activePath = updateRoutes[updateRoutes.length - 1].fullPath;
|
||||
router.push(activePath);
|
||||
this.setActiveMultiTab(activePath);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 删除所有多页签只保留路由首页
|
||||
* @param exclude - 保留的多页签
|
||||
*/
|
||||
clearMultiTab(exclude: string[] = []) {
|
||||
const remain = [ROUTE_HOME.path, ...exclude];
|
||||
const { routes } = this.multiTab;
|
||||
const updateRoutes = routes.filter(v => remain.includes(v.fullPath));
|
||||
this.multiTab.routes = updateRoutes;
|
||||
const activePath = updateRoutes[updateRoutes.length - 1].fullPath;
|
||||
router.push(activePath);
|
||||
this.setActiveMultiTab(activePath);
|
||||
},
|
||||
/** 删除左边多页签 */
|
||||
clearLeftMultiTab(fullPath: string) {
|
||||
const { routes } = this.multiTab;
|
||||
const currentIndex = routes.findIndex(route => route.fullPath === fullPath);
|
||||
const activeIndex = this.activeMultiTabIndex;
|
||||
if (currentIndex > -1) {
|
||||
const remain = [ROUTE_HOME.path, ...routes.slice(currentIndex).map(v => v.fullPath)];
|
||||
const updateRoutes = routes.filter(v => remain.includes(v.fullPath));
|
||||
this.multiTab.routes = updateRoutes;
|
||||
if (activeIndex < currentIndex) {
|
||||
const activePath = updateRoutes[updateRoutes.length - 1].fullPath;
|
||||
router.push(activePath);
|
||||
this.setActiveMultiTab(activePath);
|
||||
}
|
||||
}
|
||||
},
|
||||
/** 删除右边多页签 */
|
||||
clearRightMultiTab(fullPath: string) {
|
||||
const { routes } = this.multiTab;
|
||||
const currentIndex = routes.findIndex(route => route.fullPath === fullPath);
|
||||
const activeIndex = this.activeMultiTabIndex;
|
||||
if (currentIndex > -1) {
|
||||
const remain = [ROUTE_HOME.path, ...routes.slice(0, currentIndex + 1).map(v => v.fullPath)];
|
||||
const updateRoutes = routes.filter(v => remain.includes(v.fullPath));
|
||||
this.multiTab.routes = updateRoutes;
|
||||
if (activeIndex > currentIndex) {
|
||||
router.push(fullPath);
|
||||
this.setActiveMultiTab(fullPath);
|
||||
}
|
||||
}
|
||||
},
|
||||
/** 点击单个页签tab */
|
||||
handleClickTab(fullPath: string) {
|
||||
if (this.multiTab.activeRoute !== fullPath) {
|
||||
router.push(fullPath);
|
||||
this.setActiveMultiTab(fullPath);
|
||||
}
|
||||
},
|
||||
/** 设置当前路由对应的页签为激活状态 */
|
||||
setActiveMultiTab(fullPath: string) {
|
||||
this.multiTab.activeRoute = fullPath;
|
||||
},
|
||||
/** 初始化多页签数据 */
|
||||
initMultiTab() {
|
||||
const theme = useThemeStore();
|
||||
const { currentRoute } = router;
|
||||
const isHome = currentRoute.value.name === ROUTE_HOME.name;
|
||||
const home = getHomeTabRoute(currentRoute.value);
|
||||
const routes: MultiTabRoute[] = theme.multiTabStyle.isCache ? getTabRouteStorage() : [];
|
||||
const hasHome = isInTabRoutes(routes, home.fullPath);
|
||||
const hasCurrent = isInTabRoutes(routes, currentRoute.value.fullPath);
|
||||
if (!hasHome) {
|
||||
routes.unshift(home);
|
||||
}
|
||||
if (!isHome && !hasCurrent) {
|
||||
routes.push(currentRoute.value);
|
||||
}
|
||||
this.multiTab.routes = routes;
|
||||
this.setActiveMultiTab(currentRoute.value.fullPath);
|
||||
},
|
||||
/** 重新加载页面 */
|
||||
handleReload() {
|
||||
this.reloadFlag = false;
|
||||
nextTick(() => {
|
||||
this.reloadFlag = true;
|
||||
this.resetScrollBehavior();
|
||||
});
|
||||
},
|
||||
/** 打开配置抽屉 */
|
||||
openSettingDrawer() {
|
||||
this.settingDrawer.visible = true;
|
||||
},
|
||||
/** 关闭配置抽屉 */
|
||||
closeSettingDrawer() {
|
||||
this.settingDrawer.visible = false;
|
||||
}
|
||||
}
|
||||
return appStore;
|
||||
});
|
||||
|
||||
export default function useAppStore() {
|
||||
return appStore(store);
|
||||
}
|
||||
|
@ -1,48 +1,31 @@
|
||||
import { ref, computed, reactive } from 'vue';
|
||||
import type { Ref, ComputedRef } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import { store } from '@/store';
|
||||
import { clearAuthStorage, getToken, getUserInfo } from '@/utils';
|
||||
import type { UserInfo } from '@/interface';
|
||||
import { getUserInfo, getToken } from '@/utils';
|
||||
|
||||
interface AuthState {
|
||||
/** 用户token */
|
||||
token: string;
|
||||
interface AuthStore {
|
||||
/** 用户信息 */
|
||||
userInfo: UserInfo;
|
||||
userInfo: Auth.UserInfo;
|
||||
/** 用户token */
|
||||
token: Ref<string>;
|
||||
/** 是否登录 */
|
||||
isLogin: ComputedRef<boolean>;
|
||||
/** 用户角色 */
|
||||
role: Ref<Auth.RoleType>;
|
||||
}
|
||||
|
||||
const authStore = defineStore({
|
||||
/** 区分不通状态的唯一标识 */
|
||||
id: 'auth-store',
|
||||
/** 状态 */
|
||||
state: (): AuthState => {
|
||||
return {
|
||||
token: getToken(),
|
||||
userInfo: getUserInfo()
|
||||
};
|
||||
},
|
||||
getters: {
|
||||
/** 是否登录 */
|
||||
isLogin: state => Boolean(state.token)
|
||||
},
|
||||
actions: {
|
||||
/** 设置Auth状态 */
|
||||
setAuthState(data: Partial<AuthState>) {
|
||||
Object.assign(this, data);
|
||||
},
|
||||
/** 重置auth状态 */
|
||||
resetAuthState() {
|
||||
clearAuthStorage();
|
||||
this.$reset();
|
||||
},
|
||||
/** 判断用户权益是否变更 */
|
||||
getIsAuthChange() {
|
||||
const token = getToken();
|
||||
const tokenChange = token !== this.token;
|
||||
return tokenChange;
|
||||
}
|
||||
}
|
||||
export const useAuthStore = defineStore('auth-store', () => {
|
||||
const userInfo: Auth.UserInfo = reactive(getUserInfo());
|
||||
const token = ref(getToken());
|
||||
const isLogin = computed(() => Boolean(token.value));
|
||||
const role = ref<Auth.RoleType>('super');
|
||||
|
||||
const authStore: AuthStore = {
|
||||
userInfo,
|
||||
token,
|
||||
isLogin,
|
||||
role
|
||||
};
|
||||
|
||||
return authStore;
|
||||
});
|
||||
|
||||
export default function useAuthStore() {
|
||||
return authStore(store);
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import useThemeStore from './theme';
|
||||
import useAppStore from './app';
|
||||
import useAuthStore from './auth';
|
||||
|
||||
export { useThemeStore, useAppStore, useAuthStore };
|
||||
export * from './app';
|
||||
export * from './theme';
|
||||
export * from './auth';
|
||||
export * from './route';
|
||||
|
68
src/store/modules/route/index.ts
Normal file
68
src/store/modules/route/index.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import { ref } from 'vue';
|
||||
import type { Ref } from 'vue';
|
||||
import type { Router } from 'vue-router';
|
||||
import { defineStore } from 'pinia';
|
||||
import { constantRoutes } from '@/router';
|
||||
import { useBoolean } from '@/hooks';
|
||||
import { fetchUserRoutes } from '@/service';
|
||||
import { findAuthRouteByKey } from '@/utils';
|
||||
|
||||
/** 路由状态 */
|
||||
interface RouteStore {
|
||||
/** 动态路由 */
|
||||
routes: Ref<AuthRoute.Route[]>;
|
||||
/** 设置动态路由数据 */
|
||||
setRoutes(data: AuthRoute.Route[]): void;
|
||||
/** 是否添加过动态路由 */
|
||||
isAddedDynamicRoute: Ref<boolean>;
|
||||
/** 初始化动态路由 */
|
||||
initDynamicRoute(router: Router): Promise<void>;
|
||||
/** 获取路由名称(优先使用) */
|
||||
getRouteName(key: AuthRoute.RouteKey): AuthRoute.RouteKey;
|
||||
/** 获取路由路径 */
|
||||
getRoutePath(key: AuthRoute.RouteKey): AuthRoute.RoutePath<''> | undefined;
|
||||
/** 获取路由路径 */
|
||||
getRouteTitle(key: AuthRoute.RouteKey): string | undefined;
|
||||
}
|
||||
|
||||
export const useRouteStore = defineStore('route-store', () => {
|
||||
const routes = ref<AuthRoute.Route[]>([]);
|
||||
function setRoutes(data: AuthRoute.Route[]) {
|
||||
routes.value = data;
|
||||
}
|
||||
|
||||
const { bool: isAddedDynamicRoute, setTrue: setAddedDynamicRoute } = useBoolean();
|
||||
async function initDynamicRoute(router: Router) {
|
||||
const routes = await fetchUserRoutes();
|
||||
routes.forEach(route => {
|
||||
router.addRoute(route);
|
||||
});
|
||||
setAddedDynamicRoute();
|
||||
}
|
||||
|
||||
function getRouteName(key: AuthRoute.RouteKey) {
|
||||
return key;
|
||||
}
|
||||
function getRoutePath(key: AuthRoute.RouteKey) {
|
||||
const allRoutes = [...constantRoutes, ...routes.value];
|
||||
const item = findAuthRouteByKey(key, allRoutes);
|
||||
return item?.path;
|
||||
}
|
||||
function getRouteTitle(key: AuthRoute.RouteKey) {
|
||||
const allRoutes = [...constantRoutes, ...routes.value];
|
||||
const item = findAuthRouteByKey(key, allRoutes);
|
||||
return item?.meta?.title;
|
||||
}
|
||||
|
||||
const routeStore: RouteStore = {
|
||||
routes,
|
||||
setRoutes,
|
||||
isAddedDynamicRoute,
|
||||
initDynamicRoute,
|
||||
getRouteName,
|
||||
getRoutePath,
|
||||
getRouteTitle
|
||||
};
|
||||
|
||||
return routeStore;
|
||||
});
|
@ -1,39 +0,0 @@
|
||||
import { brightenColor, darkenColor, addColorAlpha } from '@/utils';
|
||||
|
||||
type ColorType = 'primary' | 'info' | 'success' | 'warning' | 'error';
|
||||
|
||||
type ColorScene = '' | 'Suppl' | 'Hover' | 'Pressed' | 'Active';
|
||||
|
||||
type ColorKey = `${ColorType}Color${ColorScene}`;
|
||||
|
||||
type ThemeColor = {
|
||||
[key in ColorKey]?: string;
|
||||
};
|
||||
|
||||
interface ColorAction {
|
||||
scene: ColorScene;
|
||||
handler: (color: string) => string;
|
||||
}
|
||||
|
||||
/** 获取主题颜色的各种场景对应的颜色 */
|
||||
export function getThemeColors(colors: [ColorType, string][]) {
|
||||
const colorActions: ColorAction[] = [
|
||||
{ scene: '', handler: color => color },
|
||||
{ scene: 'Suppl', handler: color => color },
|
||||
{ scene: 'Hover', handler: color => brightenColor(color) },
|
||||
{ scene: 'Pressed', handler: color => darkenColor(color) },
|
||||
{ scene: 'Active', handler: color => addColorAlpha(color, 0.1) }
|
||||
];
|
||||
|
||||
const themeColor: ThemeColor = {};
|
||||
|
||||
colors.forEach(color => {
|
||||
colorActions.forEach(action => {
|
||||
const [colorType, colorValue] = color;
|
||||
const colorKey: ColorKey = `${colorType}Color${action.scene}`;
|
||||
themeColor[colorKey] = action.handler(colorValue);
|
||||
});
|
||||
});
|
||||
|
||||
return themeColor;
|
||||
}
|
@ -1,138 +1,7 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import type { GlobalThemeOverrides } from 'naive-ui';
|
||||
import { themeSettings, defaultThemeSettings } from '@/settings';
|
||||
import { store } from '@/store';
|
||||
import type { ThemeSettings, NavMode, MultiTabMode, AnimateType, HorizontalMenuPosition } from '@/interface';
|
||||
import { getThemeColors } from './helpers';
|
||||
|
||||
type ThemeState = ThemeSettings;
|
||||
// interface ThemeStore {
|
||||
// primary: string;
|
||||
// }
|
||||
|
||||
const themeStore = defineStore({
|
||||
id: 'theme-store',
|
||||
state: (): ThemeState => ({
|
||||
...themeSettings
|
||||
}),
|
||||
getters: {
|
||||
/** naive UI主题配置 */
|
||||
themeOverrids(): GlobalThemeOverrides {
|
||||
const {
|
||||
themeColor,
|
||||
otherColor: { info, success, warning, error }
|
||||
} = this;
|
||||
|
||||
const themeColors = getThemeColors([
|
||||
['primary', themeColor],
|
||||
['info', info],
|
||||
['success', success],
|
||||
['warning', warning],
|
||||
['error', error]
|
||||
]);
|
||||
|
||||
const colorLoading = themeColor;
|
||||
|
||||
return {
|
||||
common: {
|
||||
...themeColors
|
||||
},
|
||||
LoadingBar: {
|
||||
colorLoading
|
||||
}
|
||||
};
|
||||
},
|
||||
isVerticalNav(): boolean {
|
||||
const { mode } = this.navStyle;
|
||||
return mode === 'vertical' || mode === 'vertical-mix';
|
||||
},
|
||||
pageAnimateType(): AnimateType | '' {
|
||||
return this.pageStyle.animate ? this.pageStyle.animateType : '';
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
/** 设置默认配置 */
|
||||
setDefaultThemeStore() {
|
||||
Object.assign(this, defaultThemeSettings);
|
||||
},
|
||||
/** 设置暗黑模式 */
|
||||
handleDarkMode(isDark: boolean) {
|
||||
this.darkMode = isDark;
|
||||
},
|
||||
/** 切换暗黑模式 */
|
||||
toggleDarkMode() {
|
||||
this.darkMode = !this.darkMode;
|
||||
},
|
||||
/** 设置系统主题颜色 */
|
||||
setThemeColor(color: string) {
|
||||
this.themeColor = color;
|
||||
},
|
||||
/** 设置导航栏模式 */
|
||||
setNavMode(mode: NavMode) {
|
||||
this.navStyle.mode = mode;
|
||||
},
|
||||
/** 更改菜单展开的宽度 */
|
||||
handleMenuWidth(width: number | null) {
|
||||
if (width !== null) {
|
||||
this.menuStyle.width = width;
|
||||
}
|
||||
},
|
||||
/** 更改混合菜单展开的宽度 */
|
||||
handleMixMenuWidth(width: number | null) {
|
||||
if (width !== null) {
|
||||
this.menuStyle.mixWidth = width;
|
||||
}
|
||||
},
|
||||
/** 更改顶部水平菜单的位置 */
|
||||
handleHorizontalMenuPosition(position: HorizontalMenuPosition) {
|
||||
this.menuStyle.horizontalPosition = position;
|
||||
},
|
||||
/** 更改头部的高度 */
|
||||
handleHeaderHeight(height: number | null) {
|
||||
if (height !== null) {
|
||||
this.headerStyle.height = height;
|
||||
}
|
||||
},
|
||||
/** 更改Tab标签的高度 */
|
||||
handleMultiTabHeight(height: number | null) {
|
||||
if (height !== null) {
|
||||
this.multiTabStyle.height = height;
|
||||
}
|
||||
},
|
||||
/** 设置多页签的显示 */
|
||||
handleMultiTabVisible(visible: boolean) {
|
||||
this.multiTabStyle.visible = visible;
|
||||
},
|
||||
/** 设置多页签的显示 */
|
||||
handleMultiTabMode(mode: MultiTabMode) {
|
||||
this.multiTabStyle.mode = mode;
|
||||
},
|
||||
/** 设置多页签缓存 */
|
||||
handleSetMultiTabCache(isCache: boolean) {
|
||||
this.multiTabStyle.isCache = isCache;
|
||||
},
|
||||
/** 设置面包屑的显示 */
|
||||
handleCrumbsVisible(visible: boolean) {
|
||||
this.crumbsStyle.visible = visible;
|
||||
},
|
||||
/** 设置面包屑图标的显示 */
|
||||
handleCrumbsIconVisible(visible: boolean) {
|
||||
this.crumbsStyle.showIcon = visible;
|
||||
},
|
||||
/** 开启页面切换动画 */
|
||||
handlePageAnimate(animate: boolean) {
|
||||
this.pageStyle.animate = animate;
|
||||
},
|
||||
/** 设置页面切换动画类型 */
|
||||
handlePageAnimateType(animateType: AnimateType) {
|
||||
if (this.pageStyle.animate) {
|
||||
this.pageStyle.animateType = animateType;
|
||||
}
|
||||
},
|
||||
/** 固定头部 */
|
||||
handleFixedHeaderAndTab(isFixed: boolean) {
|
||||
this.fixedHeaderAndTab = isFixed;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default function useThemeStore() {
|
||||
return themeStore(store);
|
||||
}
|
||||
export const useThemeStore = defineStore('theme-store', () => {});
|
||||
|
Reference in New Issue
Block a user