From 71b1c5e10cade8d1c018d0c5f63c98ba9357bab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=87=AF=E9=BE=99?= <502431556@qq.com> Date: Wed, 19 Jan 2022 16:29:35 +0800 Subject: [PATCH] feat(Layout): Add topLeft layout --- src/components/Breadcrumb/src/Breadcrumb.vue | 17 +- src/components/Collapse/src/Collapse.vue | 6 + src/components/ColorRadioPicker/index.ts | 3 - .../LocaleDropdown/src/LocaleDropdown.vue | 13 +- src/components/Logo/src/Logo.vue | 17 +- src/components/Menu/src/Menu.vue | 10 +- src/components/Screenfull/src/Screenfull.vue | 11 +- src/components/Setting/src/Setting.vue | 38 ++++- .../src/components}/ColorRadioPicker.vue | 0 .../src/components/InterfaceDisplay.vue | 12 ++ .../src/components/LayoutRadioPicker.vue | 98 +++++++++++ .../SizeDropdown/src/SizeDropdown.vue | 13 +- src/components/TagsView/src/TagsView.vue | 14 +- src/components/UserInfo/src/UserInfo.vue | 2 +- src/config/app.ts | 14 +- src/layout/Layout.vue | 118 ++----------- src/layout/components/AppView.vue | 27 +-- src/layout/components/ToolHeader.vue | 71 ++++++++ src/layout/components/useRenderLayout.tsx | 155 ++++++++++++++++++ src/locales/en.ts | 4 +- src/locales/zh-CN.ts | 4 +- src/store/modules/app.ts | 12 ++ src/styles/common.less | 25 +++ src/styles/index.less | 1 + src/styles/var.css | 8 +- src/views/Login/components/LoginForm.vue | 3 +- vite.config.ts | 3 +- windi.config.ts | 38 +++-- 28 files changed, 571 insertions(+), 166 deletions(-) delete mode 100644 src/components/ColorRadioPicker/index.ts rename src/components/{ColorRadioPicker/src => Setting/src/components}/ColorRadioPicker.vue (100%) create mode 100644 src/components/Setting/src/components/LayoutRadioPicker.vue create mode 100644 src/layout/components/ToolHeader.vue create mode 100644 src/layout/components/useRenderLayout.tsx create mode 100644 src/styles/common.less diff --git a/src/components/Breadcrumb/src/Breadcrumb.vue b/src/components/Breadcrumb/src/Breadcrumb.vue index 1ddf751..d4347fe 100644 --- a/src/components/Breadcrumb/src/Breadcrumb.vue +++ b/src/components/Breadcrumb/src/Breadcrumb.vue @@ -83,12 +83,27 @@ export default defineComponent({ diff --git a/src/components/Collapse/src/Collapse.vue b/src/components/Collapse/src/Collapse.vue index 92a2a22..2ff1907 100644 --- a/src/components/Collapse/src/Collapse.vue +++ b/src/components/Collapse/src/Collapse.vue @@ -1,6 +1,11 @@ + + + + + + + + + diff --git a/src/components/SizeDropdown/src/SizeDropdown.vue b/src/components/SizeDropdown/src/SizeDropdown.vue index b4eb478..db8fbf2 100644 --- a/src/components/SizeDropdown/src/SizeDropdown.vue +++ b/src/components/SizeDropdown/src/SizeDropdown.vue @@ -3,6 +3,12 @@ import { computed } from 'vue' import { ElDropdown, ElDropdownMenu, ElDropdownItem } from 'element-plus' import { useAppStore } from '@/store/modules/app' import { useI18n } from '@/hooks/web/useI18n' +import { propTypes } from '@/utils/propTypes' + +defineProps({ + color: propTypes.string.def('') +}) + const { t } = useI18n() const appStore = useAppStore() @@ -16,12 +22,7 @@ const setCurrentSize = (size: ElememtPlusSzie) => { - + diff --git a/src/components/TagsView/src/TagsView.vue b/src/components/TagsView/src/TagsView.vue index 4afa587..8aaf751 100644 --- a/src/components/TagsView/src/TagsView.vue +++ b/src/components/TagsView/src/TagsView.vue @@ -125,8 +125,10 @@ watch( - - + + @@ -215,11 +217,13 @@ watch( - + @@ -275,7 +279,7 @@ watch( ]" > diff --git a/src/components/UserInfo/src/UserInfo.vue b/src/components/UserInfo/src/UserInfo.vue index 9531d6c..5669e38 100644 --- a/src/components/UserInfo/src/UserInfo.vue +++ b/src/components/UserInfo/src/UserInfo.vue @@ -34,7 +34,7 @@ const loginOut = () => { - Archer + Archer diff --git a/src/config/app.ts b/src/config/app.ts index 6cc1408..843c1a2 100644 --- a/src/config/app.ts +++ b/src/config/app.ts @@ -2,7 +2,7 @@ import { useCache } from '@/hooks/web/useCache' const { wsCache } = useCache() -export type LayoutType = 'classic' | 'leftTop' | 'top' | 'test' +export type LayoutType = 'classic' | 'topLeft' | 'leftTop' | 'top' | 'test' export interface AppState { breadcrumb: boolean @@ -14,6 +14,7 @@ export interface AppState { locale: boolean tagsView: boolean logo: boolean + fixedHeader: boolean greyMode: boolean layout: LayoutType @@ -37,9 +38,10 @@ export const appModules: AppState = { locale: true, // 多语言图标 tagsView: true, // 标签页 logo: true, // logo + fixedHeader: true, // 固定toolheader greyMode: false, // 是否开始灰色模式,用于特殊悼念日 - layout: 'classic', // layout布局 + layout: wsCache.get('layout') || 'classic', // layout布局 title: 'butterfly-admin', // 标题 logoTitle: 'ButterflyAdmin', // logo标题 userInfo: 'userInfo', // 登录信息存储字段-建议每个项目换一个字段,避免与其他项目冲突 @@ -67,6 +69,12 @@ export const appModules: AppState = { // logo字体颜色 logoTitleTextColor: '#fff', // logo边框颜色 - logoBorderColor: 'inherit' + logoBorderColor: 'inherit', + // 头部背景颜色 + topHeaderBgColor: '#fff', + // 头部字体颜色 + topHeaderTextColor: 'inherit', + // 头部悬停颜色 + topHeaderHoverColor: '#f6f6f6' } } diff --git a/src/layout/Layout.vue b/src/layout/Layout.vue index ccf6a2b..e7c7cdc 100644 --- a/src/layout/Layout.vue +++ b/src/layout/Layout.vue @@ -1,100 +1,50 @@ - - - - - - - - - - - + + + + + + + + + diff --git a/src/layout/components/ToolHeader.vue b/src/layout/components/ToolHeader.vue new file mode 100644 index 0000000..fd524e1 --- /dev/null +++ b/src/layout/components/ToolHeader.vue @@ -0,0 +1,71 @@ + + + diff --git a/src/layout/components/useRenderLayout.tsx b/src/layout/components/useRenderLayout.tsx new file mode 100644 index 0000000..4cc3315 --- /dev/null +++ b/src/layout/components/useRenderLayout.tsx @@ -0,0 +1,155 @@ +import { computed } from 'vue' +import { useAppStore } from '@/store/modules/app' +import { Menu } from '@/components/Menu' +import { TagsView } from '@/components/TagsView' +import { Logo } from '@/components/Logo' +import AppView from './AppView.vue' +import ToolHeader from './ToolHeader.vue' +import { ElScrollbar } from 'element-plus' + +const appStore = useAppStore() + +// 标签页 +const tagsView = computed(() => appStore.getTagsView) + +// 菜单折叠 +const collapse = computed(() => appStore.getCollapse) + +// logo +const logo = computed(() => appStore.logo) + +// 固定头部 +const fixedHeader = computed(() => appStore.getFixedHeader) + +// 是否是移动端 +const mobile = computed(() => appStore.getMobile) + +export const useRenderLayout = () => { + const renderClassic = () => { + return ( + <> + + {logo.value ? ( + + ) : undefined} + + + + + + + + {tagsView.value ? : undefined} + + + + + + > + ) + } + + const renderTopLeft = () => { + return ( + <> + + + + + + + + + + {tagsView.value ? ( + + ) : undefined} + + + + + + > + ) + } + + return { + renderClassic, + renderTopLeft + } +} diff --git a/src/locales/en.ts b/src/locales/en.ts index a785c05..718e0c0 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -35,7 +35,9 @@ export default { localeIcon: 'Locale icon', tagsView: 'Tags view', logo: 'Logo', - greyMode: 'Grey mode' + greyMode: 'Grey mode', + fixedHeader: 'Fixed header', + headerTheme: 'Header theme' }, size: { default: 'Default', diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index d7433cf..1f633c1 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -35,7 +35,9 @@ export default { localeIcon: '多语言图标', tagsView: '标签页', logo: '标志', - greyMode: '灰色模式' + greyMode: '灰色模式', + fixedHeader: '固定头部', + headerTheme: '头部主题' }, size: { default: '默认', diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts index 066ec9e..14bcf47 100644 --- a/src/store/modules/app.ts +++ b/src/store/modules/app.ts @@ -4,6 +4,7 @@ import { useCache } from '@/hooks/web/useCache' import { appModules } from '@/config/app' import type { AppState, LayoutType } from '@/config/app' import { setCssVar, humpToUnderline } from '@/utils' +import { ElMessage } from 'element-plus' const { wsCache } = useCache() @@ -38,6 +39,9 @@ export const useAppStore = defineStore({ getLogo(): boolean { return this.logo }, + getFixedHeader(): boolean { + return this.fixedHeader + }, getGreyMode(): boolean { return this.greyMode }, @@ -98,12 +102,20 @@ export const useAppStore = defineStore({ setLogo(logo: boolean) { this.logo = logo }, + setFixedHeader(fixedHeader: boolean) { + this.fixedHeader = fixedHeader + }, setGreyMode(greyMode: boolean) { this.greyMode = greyMode }, setLayout(layout: LayoutType) { + if (this.mobile && layout !== 'classic') { + ElMessage.warning('移动端模式下不支持切换其他布局') + return + } this.layout = layout + wsCache.set('layout', this.layout) }, setTitle(title: string) { this.title = title diff --git a/src/styles/common.less b/src/styles/common.less new file mode 100644 index 0000000..4d11299 --- /dev/null +++ b/src/styles/common.less @@ -0,0 +1,25 @@ +.hover-tigger { + @apply flex h-full pt-1px px-10px cursor-pointer items-center; + transition: background var(--transition-time-02); + &:hover { + background-color: var(--top-header-hover-color); + } +} + +.border-bottom { + @apply relative; + &:after { + content: ''; + border-top: 1px solid var(--top-tool-border-color); + @apply absolute bottom-0 left-0 w-full h-1px; + } +} + +.border-top { + @apply relative; + &:before { + content: ''; + border-top: 1px solid var(--top-tool-border-color); + @apply absolute top-0 left-0 w-full h-1px; + } +} diff --git a/src/styles/index.less b/src/styles/index.less index 7442500..6cc113f 100644 --- a/src/styles/index.less +++ b/src/styles/index.less @@ -1 +1,2 @@ @import './var.css'; +@import './common.less'; diff --git a/src/styles/var.css b/src/styles/var.css index ddc392f..fc00fd5 100644 --- a/src/styles/var.css +++ b/src/styles/var.css @@ -30,13 +30,19 @@ /* logo end */ /* header start */ + --top-header-bg-color: '#fff'; + + --top-header-text-color: 'inherit'; + + --top-header-hover-color: #f6f6f6; + --top-tool-height: var(--logo-height); --top-tool-p-x: 0; --top-tool-border-color: #eee; - --tags-view-height: 40px; + --tags-view-height: 35px; /* header start */ --app-content-padding: 20px; diff --git a/src/views/Login/components/LoginForm.vue b/src/views/Login/components/LoginForm.vue index c5c03d2..ea48347 100644 --- a/src/views/Login/components/LoginForm.vue +++ b/src/views/Login/components/LoginForm.vue @@ -132,7 +132,8 @@ const signIn = async () => { addRoute(route as RouteRecordRaw) // 动态添加可访问路由表 }) permissionStore.setIsAddRouters(true) - push({ path: redirect.value || permissionStore.addRouters[0].path }) + // push({ path: redirect.value || permissionStore.addRouters[0].path }) + push({ path: permissionStore.addRouters[0].path }) } } } diff --git a/vite.config.ts b/vite.config.ts index badd545..22ec30f 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -117,7 +117,8 @@ export default ({ command, mode }: ConfigEnv): UserConfig => { }, hmr: { overlay: false - } + }, + host: '0.0.0.0' }, optimizeDeps: { include: [ diff --git a/windi.config.ts b/windi.config.ts index 56ccbf3..906ed8b 100644 --- a/windi.config.ts +++ b/windi.config.ts @@ -1,4 +1,5 @@ import { defineConfig } from 'windicss/helpers' +// import plugin from 'windicss/plugin' // function range(size, startAt = 1) { // return Array.from(Array(size).keys()).map((i) => i + startAt) @@ -34,16 +35,33 @@ export default defineConfig({ // // ...range(50).map((i) => `ml-${i}px`) // } } - // Plugin: [ - // require('@windicss/plugin-animations')({ - // settings: { - // animatedSpeed: 1000, - // heartBeatSpeed: 1000, - // hingeSpeed: 2000, - // bounceInSpeed: 750, - // bounceOutSpeed: 750, - // animationDelaySpeed: 1000 - // } + // plugins: [ + // plugin(({ addComponents }) => { + // addComponents({ + // '.hover-tigger': { + // display: 'flex', + // height: '100%', + // padding: '1px 10px 0', + // cursor: 'pointer', + // alignItems: 'center', + // transition: 'background var(--transition-time-02)', + // '&:hover': { + // backgroundColor: '#f6f6f6' + // } + // }, + // '.border-bottom': { + // position: 'relative', + // '&:after': { + // position: 'absolute', + // bottom: '0', + // left: '0', + // width: '100%', + // height: '1px', + // borderTop: '1px solid var(--top-tool-border-color)', + // content: '' + // } + // } + // }) // }) // ] })