diff --git a/.env b/.env
index fa204ea2..ce6d12fc 100644
--- a/.env
+++ b/.env
@@ -1,5 +1,5 @@
# 变量需要以VITE开头
-VITE_APP_TITLE=web-cli
-VITE_APP_TITLE_LABEL=web脚手架
+VITE_APP_TITLE=SoybeanAdmin
+VITE_APP_TITLE_LABEL=Soybean后台管理系统
VITE_BASE_URL=/
diff --git a/index.html b/index.html
index c7c16fc4..5a9c3245 100644
--- a/index.html
+++ b/index.html
@@ -4,10 +4,10 @@
-
Vite App
+ <%= title %>
-
+
diff --git a/public/favicon.ico b/public/favicon.ico
index df36fcfb..2b47ca6e 100644
Binary files a/public/favicon.ico and b/public/favicon.ico differ
diff --git a/src/assets/img/common/logo.png b/src/assets/img/common/logo.png
new file mode 100644
index 00000000..6641c827
Binary files /dev/null and b/src/assets/img/common/logo.png differ
diff --git a/src/enum/animate.ts b/src/enum/animate.ts
new file mode 100644
index 00000000..04f6ab90
--- /dev/null
+++ b/src/enum/animate.ts
@@ -0,0 +1,9 @@
+/** 动画类型 */
+export enum EnumAnimate {
+ 'zoom-fade' = '渐变',
+ 'zoom-out' = '闪现',
+ 'fade-slide' = '滑动',
+ 'fade' = '消退',
+ 'fade-bottom' = '底部消退',
+ 'fade-scale' = '缩放消退'
+}
diff --git a/src/enum/common.ts b/src/enum/common.ts
index 0eaaff0b..f4d81362 100644
--- a/src/enum/common.ts
+++ b/src/enum/common.ts
@@ -1,4 +1,4 @@
-/** 请求头的content-type类型 */
+/** http请求头的content-type类型 */
export enum ContentType {
json = 'application/json',
formUrlencoded = 'application/x-www-form-urlencoded',
diff --git a/src/enum/index.ts b/src/enum/index.ts
index 6e4371f6..99dd268d 100644
--- a/src/enum/index.ts
+++ b/src/enum/index.ts
@@ -1 +1,3 @@
export { ContentType } from './common';
+export { EnumAnimate } from './animate';
+export { EnumNavMode, EnumNavTheme } from './theme';
diff --git a/src/enum/theme.ts b/src/enum/theme.ts
new file mode 100644
index 00000000..664dd012
--- /dev/null
+++ b/src/enum/theme.ts
@@ -0,0 +1,13 @@
+/** 导航模式 */
+export enum EnumNavMode {
+ 'vertical' = '左侧菜单模式',
+ 'horizontal' = '顶部菜单模式',
+ 'horizontal-mix' = '顶部菜单混合模式'
+}
+
+/** 导航风格 */
+export enum EnumNavTheme {
+ 'dark' = '暗色侧边栏',
+ 'light' = '白色侧边栏',
+ 'header-dark' = '暗色的侧边栏和顶栏'
+}
diff --git a/src/interface/app.ts b/src/interface/app.ts
index 5c0ad0a4..3190ac88 100644
--- a/src/interface/app.ts
+++ b/src/interface/app.ts
@@ -1,3 +1,5 @@
+import { EnumAnimate, EnumNavMode, EnumNavTheme } from '@/enum';
+
export interface ThemeSettings {
/** 深色模式 */
darkMode: boolean;
@@ -7,6 +9,18 @@ export interface ThemeSettings {
themeColorList: string[];
/** 其他颜色 */
otherColor: OtherColor;
+ /** 导航样式 */
+ navStyle: NavStyle;
+ /** 头部样式 */
+ headerStyle: HeaderStyle;
+ /** 菜单样式 */
+ menuStyle: MenuStyle;
+ /** 多标签样式 */
+ multiTabStyle: MultiTabStyle;
+ /** 面包屑样式 */
+ crumbsStyle: CrumbsStyle;
+ /** 页面样式 */
+ pageStyle: PageStyle;
}
interface OtherColor {
@@ -19,3 +33,62 @@ interface OtherColor {
/** 错误 */
error: string;
}
+
+type NavMode = keyof typeof EnumNavMode;
+type NavTheme = keyof typeof EnumNavTheme;
+
+interface NavStyle {
+ /** 导航模式 */
+ mode: NavMode;
+ /** 导航主题 */
+ theme: NavTheme;
+}
+
+interface HeaderStyle {
+ /** 顶部高度 */
+ height: number;
+ /** 背景颜色 */
+ bgColor: string;
+ /** 固定顶部 */
+ fixed: boolean;
+ /** 显示重载按钮 */
+ showReload: boolean;
+}
+
+interface MenuStyle {
+ /** 折叠菜单 */
+ collapsed: boolean;
+ /** 菜单宽度 */
+ width: number;
+ /** 菜单折叠时的宽度 */
+ collapsedWidth: number;
+ /** 固定菜单 */
+ fixed: boolean;
+ /** 分割菜单 */
+ splitMenu: boolean;
+}
+
+interface MultiTabStyle {
+ /** 多标签可见 */
+ visible: boolean;
+ /** 背景颜色 */
+ bgColor: string;
+ /** 固定标签页 */
+ fixed: boolean;
+}
+
+interface CrumbsStyle {
+ /** 面包屑可见 */
+ visible: boolean;
+ /** 显示图标 */
+ showIcon: boolean;
+}
+
+type AnimateType = keyof typeof EnumAnimate;
+
+interface PageStyle {
+ /** 页面是否开启动画 */
+ animate: boolean;
+ /** 动画类型 */
+ animateType: AnimateType;
+}
diff --git a/src/layouts/BasicLayout/components/GlobalHeader/components/HeaderItemContainer.vue b/src/layouts/BasicLayout/components/GlobalHeader/components/HeaderItemContainer.vue
new file mode 100644
index 00000000..ccec0d10
--- /dev/null
+++ b/src/layouts/BasicLayout/components/GlobalHeader/components/HeaderItemContainer.vue
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/src/layouts/BasicLayout/components/GlobalHeader/components/index.ts b/src/layouts/BasicLayout/components/GlobalHeader/components/index.ts
new file mode 100644
index 00000000..c4911d8e
--- /dev/null
+++ b/src/layouts/BasicLayout/components/GlobalHeader/components/index.ts
@@ -0,0 +1,3 @@
+import HeaderItemContainer from './HeaderItemContainer.vue';
+
+export { HeaderItemContainer };
diff --git a/src/layouts/BasicLayout/components/GlobalHeader/index.vue b/src/layouts/BasicLayout/components/GlobalHeader/index.vue
new file mode 100644
index 00000000..abd51f5a
--- /dev/null
+++ b/src/layouts/BasicLayout/components/GlobalHeader/index.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
diff --git a/src/layouts/BasicLayout/components/GlobalLogo/index.vue b/src/layouts/BasicLayout/components/GlobalLogo/index.vue
new file mode 100644
index 00000000..157b6c60
--- /dev/null
+++ b/src/layouts/BasicLayout/components/GlobalLogo/index.vue
@@ -0,0 +1,16 @@
+
+
+
+ {{ title }}
+
+
+
+
+
diff --git a/src/layouts/BasicLayout/components/GlobalMenu/index.vue b/src/layouts/BasicLayout/components/GlobalMenu/index.vue
new file mode 100644
index 00000000..c5c27b65
--- /dev/null
+++ b/src/layouts/BasicLayout/components/GlobalMenu/index.vue
@@ -0,0 +1,6 @@
+
+ 菜单
+
+
+
+
diff --git a/src/layouts/BasicLayout/components/SettingDrawer/components/DarkMode.vue b/src/layouts/BasicLayout/components/SettingDrawer/components/DarkMode.vue
new file mode 100644
index 00000000..2becea9e
--- /dev/null
+++ b/src/layouts/BasicLayout/components/SettingDrawer/components/DarkMode.vue
@@ -0,0 +1,25 @@
+
+ 深色主题
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/BasicLayout/components/SettingDrawer/components/ThemeStyle.vue b/src/layouts/BasicLayout/components/SettingDrawer/components/ThemeStyle.vue
new file mode 100644
index 00000000..e69de29b
diff --git a/src/layouts/BasicLayout/components/SettingDrawer/components/index.ts b/src/layouts/BasicLayout/components/SettingDrawer/components/index.ts
new file mode 100644
index 00000000..e49edc04
--- /dev/null
+++ b/src/layouts/BasicLayout/components/SettingDrawer/components/index.ts
@@ -0,0 +1,3 @@
+import DarkMode from './DarkMode.vue';
+
+export { DarkMode };
diff --git a/src/layouts/BasicLayout/components/SettingDrawer/index.vue b/src/layouts/BasicLayout/components/SettingDrawer/index.vue
new file mode 100644
index 00000000..012c3467
--- /dev/null
+++ b/src/layouts/BasicLayout/components/SettingDrawer/index.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/BasicLayout/components/index.ts b/src/layouts/BasicLayout/components/index.ts
new file mode 100644
index 00000000..a4180a4c
--- /dev/null
+++ b/src/layouts/BasicLayout/components/index.ts
@@ -0,0 +1,6 @@
+import GlobalHeader from './GlobalHeader/index.vue';
+import GlobalLogo from './GlobalLogo/index.vue';
+import GlobalMenu from './GlobalMenu/index.vue';
+import SettingDrawer from './SettingDrawer/index.vue';
+
+export { GlobalHeader, GlobalLogo, GlobalMenu, SettingDrawer };
diff --git a/src/layouts/BasicLayout/index.vue b/src/layouts/BasicLayout/index.vue
index b480b910..edc58f96 100644
--- a/src/layouts/BasicLayout/index.vue
+++ b/src/layouts/BasicLayout/index.vue
@@ -1,15 +1,67 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
diff --git a/src/main.ts b/src/main.ts
index ab02d46d..23e10a9e 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -3,30 +3,29 @@ import App from './App.vue';
import AppProvider from './AppProvider.vue';
import { setupStore } from './store';
import { router, setupRouter } from './router';
-import { setupSmoothScroll, setupNaive } from './plugins';
+import { setupSmoothScroll, setupWindicssDarkMode } from './plugins';
import 'virtual:windi.css';
import './styles/css/global.css';
async function setupApp() {
- const naiveApp = createApp(AppProvider);
+ const appProvider = createApp(AppProvider);
const app = createApp(App);
- /** 注册naive UI组件 */
- setupNaive(app);
-
- /** 挂载全局状态 */
+ // 挂载全局状态
setupStore(app);
- // 优先挂载一下 naiveApp 解决路由守卫,Axios中可使用,LoadingBar,Dialog,Message 等之类组件
- naiveApp.mount('#naiveApp', true);
+ // 优先挂载一下 appProvider 解决路由守卫,Axios中可使用,LoadingBar,Dialog,Message 等之类组件
+ appProvider.mount('#appProvider', true);
// 挂载路由
- await setupRouter(app);
+ setupRouter(app);
// 路由准备就绪后挂载APP实例
await router.isReady();
app.mount('#app', true);
+
+ setupWindicssDarkMode();
}
setupSmoothScroll();
diff --git a/src/plugins/dark-mode.ts b/src/plugins/dark-mode.ts
new file mode 100644
index 00000000..ff35c7fd
--- /dev/null
+++ b/src/plugins/dark-mode.ts
@@ -0,0 +1,31 @@
+import { watch } from 'vue';
+import { useAppStore } from '@/store';
+
+export default function setupWindicssDarkMode() {
+ const app = useAppStore();
+
+ const DARK_CLASS = 'dark';
+ function getHtmlElement() {
+ return document.querySelector('html')!;
+ }
+
+ function addDarkClass() {
+ const html = getHtmlElement();
+ html.classList.add(DARK_CLASS);
+ }
+ function removeDarkClass() {
+ const html = getHtmlElement();
+ html.classList.remove(DARK_CLASS);
+ }
+
+ watch(
+ () => app.themeSettings.darkMode,
+ newValue => {
+ if (newValue) {
+ addDarkClass();
+ } else {
+ removeDarkClass();
+ }
+ }
+ );
+}
diff --git a/src/plugins/index.ts b/src/plugins/index.ts
index e0557b2e..ba9de06c 100644
--- a/src/plugins/index.ts
+++ b/src/plugins/index.ts
@@ -1,4 +1,5 @@
import setupSmoothScroll from './smooth-scroll';
import setupNaive from './naive';
+import setupWindicssDarkMode from './dark-mode';
-export { setupSmoothScroll, setupNaive };
+export { setupSmoothScroll, setupNaive, setupWindicssDarkMode };
diff --git a/src/settings/theme/index.ts b/src/settings/theme/index.ts
index 5523b0c2..001694ca 100644
--- a/src/settings/theme/index.ts
+++ b/src/settings/theme/index.ts
@@ -23,18 +23,44 @@ const themeColorList = [
];
const themeSettings: ThemeSettings = {
- /** 深色主题 */
darkMode: false,
- /** 系统主题色 */
themeColor: themeColorList[0],
- /** 系统内置主题色列表 */
themeColorList,
- /** 其他颜色 */
otherColor: {
info: '#2080f0',
success: '#67C23A',
warning: '#E6A23C',
error: '#F56C6C'
+ },
+ navStyle: {
+ mode: 'vertical',
+ theme: 'light'
+ },
+ headerStyle: {
+ height: 64,
+ bgColor: '#fff',
+ fixed: true,
+ showReload: true
+ },
+ menuStyle: {
+ collapsed: false,
+ width: 200,
+ collapsedWidth: 64,
+ fixed: true,
+ splitMenu: false
+ },
+ multiTabStyle: {
+ visible: true,
+ bgColor: '#fff',
+ fixed: true
+ },
+ crumbsStyle: {
+ visible: true,
+ showIcon: false
+ },
+ pageStyle: {
+ animate: true,
+ animateType: 'zoom-fade'
}
};
diff --git a/src/store/modules/app/index.ts b/src/store/modules/app/index.ts
index b91e7e91..cab27621 100644
--- a/src/store/modules/app/index.ts
+++ b/src/store/modules/app/index.ts
@@ -1,22 +1,28 @@
import { defineStore } from 'pinia';
import type { GlobalThemeOverrides } from 'naive-ui';
-import { store } from '../../index';
import { themeSettings } from '@/settings';
import type { ThemeSettings } from '@/interface';
+import { store } from '../../index';
import { getHoverAndPressedColor } from './helpers';
interface AppState {
/** 主题配置 */
themeSettings: ThemeSettings;
- /** 侧边栏折叠 */
- asideCollapse: boolean;
+ /** 主题配置抽屉 */
+ settingDrawer: SettingDrawer;
+}
+
+interface SettingDrawer {
+ visible: boolean;
}
const appStore = defineStore({
id: 'app-store',
state: (): AppState => ({
themeSettings,
- asideCollapse: false
+ settingDrawer: {
+ visible: false
+ }
}),
getters: {
/** naive UI主题配置 */
@@ -59,11 +65,21 @@ const appStore = defineStore({
}
},
actions: {
- handleAsideCollapse(collapse: boolean) {
- this.asideCollapse = collapse;
+ /** 折叠/展开菜单 */
+ handleMenuCollapse(collapsed: boolean) {
+ this.themeSettings.menuStyle.collapsed = collapsed;
},
- toggleAside() {
- this.asideCollapse = !this.asideCollapse;
+ /** 切换折叠/展开菜单 */
+ toggleMenu() {
+ this.themeSettings.menuStyle.collapsed = !this.themeSettings.menuStyle.collapsed;
+ },
+ /** 打开配置抽屉 */
+ openSettingDrawer() {
+ this.settingDrawer.visible = true;
+ },
+ /** 关闭配置抽屉 */
+ closeSettingDrawer() {
+ this.settingDrawer.visible = false;
}
}
});
diff --git a/src/views/home/index.vue b/src/views/home/index.vue
index 5a5dd101..ae2718e8 100644
--- a/src/views/home/index.vue
+++ b/src/views/home/index.vue
@@ -25,7 +25,7 @@
+