diff --git a/build/vite/index.ts b/build/vite/index.ts index d5b6a4ac..02067107 100644 --- a/build/vite/index.ts +++ b/build/vite/index.ts @@ -1,7 +1,6 @@ import { resolve } from 'path' import Vue from '@vitejs/plugin-vue' import VueJsx from '@vitejs/plugin-vue-jsx' -import WindiCSS from 'vite-plugin-windicss' import progress from 'vite-plugin-progress' import EslintPlugin from 'vite-plugin-eslint' import PurgeIcons from 'vite-plugin-purge-icons' @@ -15,6 +14,7 @@ import viteCompression from 'vite-plugin-compression' import topLevelAwait from 'vite-plugin-top-level-await' import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite' import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' +import UnoCSS from 'unocss/vite' export function createVitePlugins() { const root = process.cwd() @@ -27,7 +27,7 @@ export function createVitePlugins() { return [ Vue(), VueJsx(), - WindiCSS(), + UnoCSS(), progress(), PurgeIcons(), ElementPlus({}), diff --git a/package.json b/package.json index a2a60d54..e6be32f8 100644 --- a/package.json +++ b/package.json @@ -87,9 +87,11 @@ "@types/qs": "^6.9.7", "@typescript-eslint/eslint-plugin": "^6.2.0", "@typescript-eslint/parser": "^6.2.0", + "@unocss/transformer-variant-group": "^0.51.4", "@vitejs/plugin-legacy": "^4.1.1", "@vitejs/plugin-vue": "^4.2.3", "@vitejs/plugin-vue-jsx": "^3.0.1", + "@vue-macros/volar": "^0.12.3", "autoprefixer": "^10.4.14", "bpmn-js": "^8.9.0", "bpmn-js-properties-panel": "^0.46.0", @@ -114,6 +116,7 @@ "stylelint-order": "^6.0.3", "terser": "^5.19.2", "typescript": "5.1.6", + "unocss": "^0.54.0", "unplugin-auto-import": "^0.16.6", "unplugin-element-plus": "^0.7.2", "unplugin-vue-components": "^0.25.1", @@ -125,9 +128,7 @@ "vite-plugin-purge-icons": "^0.9.2", "vite-plugin-svg-icons": "^2.0.1", "vite-plugin-top-level-await": "^1.3.1", - "vite-plugin-windicss": "^1.9.0", - "vue-tsc": "^1.8.8", - "windicss": "^3.5.6" + "vue-tsc": "^1.8.8" }, "license": "MIT", "repository": { diff --git a/src/components/ContentDetailWrap/src/ContentDetailWrap.vue b/src/components/ContentDetailWrap/src/ContentDetailWrap.vue index 298202b1..1446d9a7 100644 --- a/src/components/ContentDetailWrap/src/ContentDetailWrap.vue +++ b/src/components/ContentDetailWrap/src/ContentDetailWrap.vue @@ -28,7 +28,7 @@ onMounted(() => { <div :class="[ `${prefixCls}-header`, - 'flex border-bottom-1 h-50px items-center text-center pr-10px' + 'lex b-b-1 h-50px items-center text-center bg-white pr-10px' ]" > <div :class="[`${prefixCls}-header__back`, 'flex pl-10px pr-10px ']"> diff --git a/src/components/Descriptions/src/Descriptions.vue b/src/components/Descriptions/src/Descriptions.vue index 0baa396c..06e1096a 100644 --- a/src/components/Descriptions/src/Descriptions.vue +++ b/src/components/Descriptions/src/Descriptions.vue @@ -71,14 +71,14 @@ const toggleClick = () => { <div :class="[ prefixCls, - 'bg-[var(--el-color-white)] dark:(bg-[var(--el-bg-color)] border-[var(--el-border-color)] border-1px)' + 'bg-[var(--el-color-white)] dark:bg-[var(--el-bg-color)] dark:border-[var(--el-border-color)] dark:border-1px' ]" > <div v-if="title" :class="[ `${prefixCls}-header`, - 'h-50px flex justify-between items-center border-bottom-1 border-solid border-[var(--tags-view-border-color)] px-10px cursor-pointer dark:border-[var(--el-border-color)]' + 'h-50px flex justify-between items-center b-b-1 border-solid border-[var(--el-border-color)] px-10px cursor-pointer dark:border-[var(--el-border-color)]' ]" @click="toggleClick" > diff --git a/src/components/Dialog/src/Dialog.vue b/src/components/Dialog/src/Dialog.vue index c1114d36..5fd298bb 100644 --- a/src/components/Dialog/src/Dialog.vue +++ b/src/components/Dialog/src/Dialog.vue @@ -99,13 +99,19 @@ const dialogStyle = computed(() => { </template> <style lang="scss"> -.#{$elNamespace}-dialog__header { - margin-right: 0 !important; - border-bottom: 1px solid var(--tags-view-border-color); -} +.#{$elNamespace}-dialog { + &__header { + margin-right: 0 !important; + border-bottom: 1px solid var(--el-border-color); + } -.#{$elNamespace}-dialog__footer { - border-top: 1px solid var(--tags-view-border-color); + &__body { + padding: 0 !important; + } + + &__footer { + border-top: 1px solid var(--el-border-color); + } } .is-hover { @@ -113,14 +119,4 @@ const dialogStyle = computed(() => { color: var(--el-color-primary) !important; } } - -.dark { - .#{$elNamespace}-dialog__header { - border-bottom: 1px solid var(--el-border-color); - } - - .#{$elNamespace}-dialog__footer { - border-top: 1px solid var(--el-border-color); - } -} </style> diff --git a/src/components/Editor/src/Editor.vue b/src/components/Editor/src/Editor.vue index 3b2013d1..d972552d 100644 --- a/src/components/Editor/src/Editor.vue +++ b/src/components/Editor/src/Editor.vue @@ -164,7 +164,6 @@ const handleChange = (editor: IDomEditor) => { // 组件销毁时,及时销毁编辑器 onBeforeUnmount(() => { const editor = unref(editorRef.value) - if (editor === null) return // 销毁,并移除 editor editor?.destroy() @@ -181,12 +180,12 @@ defineExpose({ </script> <template> - <div class="border-1 border-solid border-[var(--tags-view-border-color)] z-99"> + <div class="border-1 border-solid border-[var(--el-border-color)] z-99"> <!-- 工具栏 --> <Toolbar :editor="editorRef" :editorId="editorId" - class="border-bottom-1 border-solid border-[var(--tags-view-border-color)]" + class="border-0 b-b-1 border-solid border-[var(--el-border-color)]" /> <!-- 编辑器 --> <Editor diff --git a/src/layout/components/AppView.vue b/src/layout/components/AppView.vue index fe480b55..ffdf11f5 100644 --- a/src/layout/components/AppView.vue +++ b/src/layout/components/AppView.vue @@ -18,26 +18,33 @@ const tagsViewStore = useTagsViewStore() const getCaches = computed((): string[] => { return tagsViewStore.getCachedViews }) + +const tagsView = computed(() => appStore.getTagsView) </script> <template> <section :class="[ - 'p-[var(--app-content-padding)] w-[100%] bg-[var(--app-content-bg-color)] dark:bg-[var(--el-bg-color)]', + 'p-[var(--app-content-padding)] w-[calc(100%-var(--app-content-padding)-var(--app-content-padding))] bg-[var(--app-content-bg-color)] dark:bg-[var(--el-bg-color)]', { - '!min-h-[calc(100%-var(--app-footer-height))]': - ((fixedHeader && (layout === 'classic' || layout === 'topLeft')) || layout === 'top') && - footer, + '!min-h-[calc(100%-var(--app-content-padding)-var(--app-content-padding)-var(--app-footer-height))]': + (fixedHeader && + (layout === 'classic' || layout === 'topLeft' || layout === 'top') && + footer) || + (!tagsView && layout === 'top' && footer), + '!min-h-[calc(100%-var(--app-content-padding)-var(--app-content-padding)-var(--app-footer-height)-var(--tags-view-height))]': + tagsView && layout === 'top' && footer, - '!min-h-[calc(100%-var(--tags-view-height)-var(--top-tool-height)-var(--app-footer-height))]': + '!min-h-[calc(100%-var(--tags-view-height)-var(--app-content-padding)-var(--app-content-padding)-var(--top-tool-height)-var(--app-footer-height))]': !fixedHeader && layout === 'classic' && footer, - '!min-h-[calc(100%-var(--tags-view-height)-var(--app-footer-height))]': - !fixedHeader && (layout === 'topLeft' || layout === 'top') && footer, + '!min-h-[calc(100%-var(--tags-view-height)-var(--app-content-padding)-var(--app-content-padding)-var(--app-footer-height))]': + !fixedHeader && layout === 'topLeft' && footer, - '!min-h-[calc(100%-var(--top-tool-height))]': fixedHeader && layout === 'cutMenu' && footer, + '!min-h-[calc(100%-var(--top-tool-height)-var(--app-content-padding)-var(--app-content-padding))]': + fixedHeader && layout === 'cutMenu' && footer, - '!min-h-[calc(100%-var(--top-tool-height)-var(--tags-view-height))]': + '!min-h-[calc(100%-var(--top-tool-height)-var(--app-content-padding)-var(--app-content-padding)-var(--tags-view-height))]': !fixedHeader && layout === 'cutMenu' && footer } ]" diff --git a/src/layout/components/LocaleDropdown/src/LocaleDropdown.vue b/src/layout/components/LocaleDropdown/src/LocaleDropdown.vue index f7e3632a..95132db2 100644 --- a/src/layout/components/LocaleDropdown/src/LocaleDropdown.vue +++ b/src/layout/components/LocaleDropdown/src/LocaleDropdown.vue @@ -38,7 +38,7 @@ const setLang = (lang: LocaleType) => { :class="$attrs.class" :color="color" :size="18" - class="cursor-pointer" + class="cursor-pointer !p-0" icon="ion:language-sharp" /> <template #dropdown> diff --git a/src/layout/components/Logo/src/Logo.vue b/src/layout/components/Logo/src/Logo.vue index 72620168..71856fff 100644 --- a/src/layout/components/Logo/src/Logo.vue +++ b/src/layout/components/Logo/src/Logo.vue @@ -62,8 +62,7 @@ watch( :class="[ prefixCls, layout !== 'classic' ? `${prefixCls}__Top` : '', - 'flex !h-[var(--logo-height)] items-center cursor-pointer justify-center relative', - 'dark:bg-[var(--el-bg-color)]' + 'flex !h-[var(--logo-height)] items-center cursor-pointer pl-8px relative decoration-none overflow-hidden' ]" to="/" > diff --git a/src/layout/components/Menu/src/Menu.vue b/src/layout/components/Menu/src/Menu.vue index 73f48fd6..51d0c61b 100644 --- a/src/layout/components/Menu/src/Menu.vue +++ b/src/layout/components/Menu/src/Menu.vue @@ -138,15 +138,6 @@ $prefix-cls: #{$namespace}-menu; position: relative; transition: width var(--transition-time-02); - &:after { - position: absolute; - top: 0; - right: 0; - height: 100%; - border-left: 1px solid var(--left-menu-border-color); - content: ''; - } - :deep(.#{$elNamespace}-menu) { width: 100% !important; border-right: none; diff --git a/src/layout/components/Setting/src/Setting.vue b/src/layout/components/Setting/src/Setting.vue index 28fc45c5..00d0a8fe 100644 --- a/src/layout/components/Setting/src/Setting.vue +++ b/src/layout/components/Setting/src/Setting.vue @@ -44,7 +44,6 @@ const setHeaderTheme = (color: string) => { setCssVar('--top-header-bg-color', color) setCssVar('--top-header-text-color', textColor) setCssVar('--top-header-hover-color', textHoverColor) - setCssVar('--top-tool-border-color', topToolBorderColor) appStore.setTheme({ topHeaderBgColor: color, topHeaderTextColor: textColor, diff --git a/src/layout/components/TabMenu/src/TabMenu.vue b/src/layout/components/TabMenu/src/TabMenu.vue index a5a58ad2..061c5a39 100644 --- a/src/layout/components/TabMenu/src/TabMenu.vue +++ b/src/layout/components/TabMenu/src/TabMenu.vue @@ -139,7 +139,7 @@ export default defineComponent({ id={`${variables.namespace}-menu`} class={[ prefixCls, - 'relative bg-[var(--left-menu-bg-color)] top-1px z-3000', + 'relative bg-[var(--left-menu-bg-color)] top-1px z-3000 layout-border__right', { 'w-[var(--tab-menu-max-width)]': !unref(collapse), 'w-[var(--tab-menu-min-width)]': unref(collapse) @@ -195,7 +195,7 @@ export default defineComponent({ </div> <Menu class={[ - '!absolute top-0 border-left-1 border-solid border-[var(--left-menu-bg-light-color)]', + '!absolute top-0', { '!left-[var(--tab-menu-min-width)]': unref(collapse), '!left-[var(--tab-menu-max-width)]': !unref(collapse), @@ -217,16 +217,6 @@ $prefix-cls: #{$namespace}-tab-menu; .#{$prefix-cls} { transition: all var(--transition-time-02); - &::after { - position: absolute; - top: 0; - right: 0; - width: 1px; - height: 100%; - border-left: 1px solid var(--left-menu-border-color); - content: ''; - } - &__item { color: var(--left-menu-text-color); transition: all var(--transition-time-02); @@ -240,7 +230,6 @@ $prefix-cls: #{$namespace}-tab-menu; &--collapse { color: var(--left-menu-text-color); background-color: var(--left-menu-bg-light-color); - border-top: 1px solid var(--left-menu-border-color); } .is-active { diff --git a/src/layout/components/TagsView/src/TagsView.vue b/src/layout/components/TagsView/src/TagsView.vue index 269b97b2..4770989f 100644 --- a/src/layout/components/TagsView/src/TagsView.vue +++ b/src/layout/components/TagsView/src/TagsView.vue @@ -1,17 +1,17 @@ <script lang="ts" setup> +import { onMounted, watch, computed, unref, ref, nextTick } from 'vue' +import { useRouter } from 'vue-router' import type { RouteLocationNormalizedLoaded, RouterLinkProps } from 'vue-router' import { usePermissionStore } from '@/store/modules/permission' import { useTagsViewStore } from '@/store/modules/tagsView' import { useAppStore } from '@/store/modules/app' - +import { useI18n } from '@/hooks/web/useI18n' import { filterAffixTags } from './helper' import { ContextMenu, ContextMenuExpose } from '@/layout/components/ContextMenu' import { useDesign } from '@/hooks/web/useDesign' +import { useTemplateRefsList } from '@vueuse/core' import { ElScrollbar } from 'element-plus' import { useScrollTo } from '@/hooks/event/useScrollTo' -import { useTemplateRefsList } from '@vueuse/core' - -defineOptions({ name: 'TagsView' }) const { getPrefixCls } = useDesign() @@ -35,6 +35,8 @@ const appStore = useAppStore() const tagsViewIcon = computed(() => appStore.getTagsViewIcon) +const isDark = computed(() => appStore.getIsDark) + // 初始化tag const initTags = () => { affixTagArr.value = filterAffixTags(unref(routers)) @@ -73,7 +75,7 @@ const closeAllTags = () => { toLastView() } -// 关闭其他 +// 关闭其它 const closeOthersTags = () => { tagsViewStore.delOthersViews(unref(selectedTag) as RouteLocationNormalizedLoaded) } @@ -128,6 +130,7 @@ const moveToCurrentTag = async () => { if (v.fullPath !== unref(currentRoute).fullPath) { tagsViewStore.updateVisitedView(unref(currentRoute)) } + break } } @@ -263,29 +266,21 @@ watch( class="flex w-full relative bg-[#fff] dark:bg-[var(--el-bg-color)]" > <span - :class="`${prefixCls}__tool`" - class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] cursor-pointer" + :class="`${prefixCls}__tool ${prefixCls}__tool--first`" + class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] flex items-center justify-center cursor-pointer" @click="move(-200)" > <Icon - :color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'" icon="ep:d-arrow-left" + color="var(--el-text-color-placeholder)" + :hover-color="isDark ? '#fff' : 'var(--el-color-black)'" /> </span> <div class="overflow-hidden flex-1"> <ElScrollbar ref="scrollbarRef" class="h-full" @scroll="scroll"> <div class="flex h-full"> <ContextMenu - v-for="item in visitedViews" - :key="item.fullPath" :ref="itemRefs.set" - :class="[ - `${prefixCls}__item`, - item?.meta?.affix ? `${prefixCls}__item--affix` : '', - { - 'is-active': isActive(item) - } - ]" :schema="[ { icon: 'ep:refresh', @@ -343,14 +338,23 @@ watch( } } ]" + v-for="item in visitedViews" + :key="item.fullPath" :tag-item="item" + :class="[ + `${prefixCls}__item`, + item?.meta?.affix ? `${prefixCls}__item--affix` : '', + { + 'is-active': isActive(item) + } + ]" @visible-change="visibleChange" > <div> - <router-link :ref="tagLinksRefs.set" v-slot="{ navigate }" :to="{ ...item }" custom> + <router-link :ref="tagLinksRefs.set" :to="{ ...item }" custom v-slot="{ navigate }"> <div - class="h-full flex justify-center items-center whitespace-nowrap pl-15px" @click="navigate" + class="h-full flex justify-center items-center whitespace-nowrap pl-15px" > <Icon v-if=" @@ -366,9 +370,9 @@ watch( {{ t(item?.meta?.title as string) }} <Icon :class="`${prefixCls}__item--close`" - :size="12" color="#333" icon="ep:close" + :size="12" @click.prevent.stop="closeSelectedTag(item)" /> </div> @@ -380,25 +384,28 @@ watch( </div> <span :class="`${prefixCls}__tool`" - class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer" + class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] flex items-center justify-center cursor-pointer" @click="move(200)" > <Icon - :color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'" icon="ep:d-arrow-right" + color="var(--el-text-color-placeholder)" + :hover-color="isDark ? '#fff' : 'var(--el-color-black)'" /> </span> <span :class="`${prefixCls}__tool`" - class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer" + class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] flex items-center justify-center cursor-pointer" @click="refreshSelectedTag(selectedTag)" > <Icon - :color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'" icon="ep:refresh-right" + color="var(--el-text-color-placeholder)" + :hover-color="isDark ? '#fff' : 'var(--el-color-black)'" /> </span> <ContextMenu + trigger="click" :schema="[ { icon: 'ep:refresh', @@ -450,15 +457,15 @@ watch( } } ]" - trigger="click" > <span :class="`${prefixCls}__tool`" - class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] text-center leading-[var(--tags-view-height)] cursor-pointer block" + class="w-[var(--tags-view-height)] h-[var(--tags-view-height)] flex items-center justify-center cursor-pointer block" > <Icon - :color="appStore.getIsDark ? 'var(--el-text-color-regular)' : '#333'" icon="ep:menu" + color="var(--el-text-color-placeholder)" + :hover-color="isDark ? '#fff' : 'var(--el-color-black)'" /> </span> </ContextMenu> @@ -475,47 +482,49 @@ $prefix-cls: #{$namespace}-tags-view; &__tool { position: relative; - display: inline-flex; - align-items: center; - justify-content: center; - &:hover { - :deep(span) { - color: var(--el-color-black) !important; - } - } - - &::after { + &::before { position: absolute; top: 1px; left: 0; width: 100%; height: calc(100% - 1px); - border-right: 1px solid var(--tags-view-border-color); - border-left: 1px solid var(--tags-view-border-color); + border-left: 1px solid var(--el-border-color); content: ''; } + + &--first { + &::before { + position: absolute; + top: 1px; + left: 0; + width: 100%; + height: calc(100% - 1px); + border-right: 1px solid var(--el-border-color); + border-left: none; + content: ''; + } + } } &__item { position: relative; top: 2px; - height: calc(100% - 4px); - padding-right: 16px; + height: calc(100% - 6px); + padding-right: 25px; margin-left: 4px; font-size: 12px; - border-radius: 3px; cursor: pointer; border: 1px solid #d9d9d9; + border-radius: 2px; &--close { position: absolute; top: 50%; - right: 3px; + right: 5px; display: none; transform: translate(0, -50%); } - &:not(.#{$prefix-cls}__item--affix):hover { .#{$prefix-cls}__item--close { display: block; @@ -533,7 +542,6 @@ $prefix-cls: #{$namespace}-tags-view; color: var(--el-color-white); background-color: var(--el-color-primary); border: 1px solid var(--el-color-primary); - .#{$prefix-cls}__item--close { :deep(span) { color: var(--el-color-white) !important; @@ -545,26 +553,14 @@ $prefix-cls: #{$namespace}-tags-view; .dark { .#{$prefix-cls} { &__tool { - &:hover { - :deep(span) { - color: #fff !important; + &--first { + &::after { + display: none; } } - - &::after { - border-right: 1px solid var(--el-border-color); - border-left: 1px solid var(--el-border-color); - } } &__item { - position: relative; - top: 2px; - height: calc(100% - 4px); - padding-right: 16px; - font-size: 12px; - border-radius: 3px; - cursor: pointer; border: 1px solid var(--el-border-color); } @@ -577,7 +573,7 @@ $prefix-cls: #{$namespace}-tags-view; &__item.is-active { color: var(--el-color-white); background-color: var(--el-color-primary); - + border: 1px solid var(--el-color-primary); .#{$prefix-cls}__item--close { :deep(span) { color: var(--el-color-white) !important; diff --git a/src/layout/components/ToolHeader.vue b/src/layout/components/ToolHeader.vue index 49307773..ec7882de 100644 --- a/src/layout/components/ToolHeader.vue +++ b/src/layout/components/ToolHeader.vue @@ -52,28 +52,28 @@ export default defineComponent({ {layout.value !== 'top' ? ( <div class="h-full flex items-center"> {hamburger.value && layout.value !== 'cutMenu' ? ( - <Collapse class="hover-trigger" color="var(--top-header-text-color)"></Collapse> + <Collapse class="custom-hover" color="var(--top-header-text-color)"></Collapse> ) : undefined} - {breadcrumb.value ? <Breadcrumb class="<md:hidden"></Breadcrumb> : undefined} + {breadcrumb.value ? <Breadcrumb class="lt-md:hidden"></Breadcrumb> : undefined} </div> ) : undefined} <div class="h-full flex items-center"> {screenfull.value ? ( - <Screenfull class="hover-trigger" color="var(--top-header-text-color)"></Screenfull> + <Screenfull class="custom-hover" color="var(--top-header-text-color)"></Screenfull> ) : undefined} {size.value ? ( - <SizeDropdown class="hover-trigger" color="var(--top-header-text-color)"></SizeDropdown> + <SizeDropdown class="custom-hover" color="var(--top-header-text-color)"></SizeDropdown> ) : undefined} {locale.value ? ( <LocaleDropdown - class="hover-trigger" + class="custom-hover" color="var(--top-header-text-color)" ></LocaleDropdown> ) : undefined} {message.value ? ( - <Message class="hover-trigger" color="var(--top-header-text-color)"></Message> + <Message class="custom-hover" color="var(--top-header-text-color)"></Message> ) : undefined} - <UserInfo class="hover-trigger"></UserInfo> + <UserInfo></UserInfo> </div> </div> ) diff --git a/src/layout/components/UserInfo/src/UserInfo.vue b/src/layout/components/UserInfo/src/UserInfo.vue index 181be07d..c5fc9a4d 100644 --- a/src/layout/components/UserInfo/src/UserInfo.vue +++ b/src/layout/components/UserInfo/src/UserInfo.vue @@ -51,7 +51,7 @@ const toDocument = () => { </script> <template> - <ElDropdown :class="prefixCls" trigger="click"> + <ElDropdown class="custom-hover" :class="prefixCls" trigger="click"> <div class="flex items-center"> <img :src="avatar" alt="" class="w-[calc(var(--logo-height)-25px)] rounded-[50%]" /> <span class="<lg:hidden text-14px pl-[5px] text-[var(--top-header-text-color)]"> diff --git a/src/layout/components/useRenderLayout.tsx b/src/layout/components/useRenderLayout.tsx index ab42e43f..46a1e60e 100644 --- a/src/layout/components/useRenderLayout.tsx +++ b/src/layout/components/useRenderLayout.tsx @@ -39,11 +39,16 @@ export const useRenderLayout = () => { const renderClassic = () => { return ( <> - <div class={['absolute top-0 left-0 h-full', { '!fixed z-3000': mobile.value }]}> + <div + class={[ + 'absolute top-0 left-0 h-full layout-border__right', + { '!fixed z-3000': mobile.value } + ]} + > {logo.value ? ( <Logo class={[ - 'bg-[var(--left-menu-bg-color)] border-bottom-1 border-solid border-[var(--logo-border-color)] dark:border-[var(--el-border-color)]', + 'bg-[var(--left-menu-bg-color)] relative', { '!pl-0': mobile.value && collapse.value, 'w-[var(--left-menu-min-width)]': appStore.getCollapse, @@ -83,19 +88,26 @@ export const useRenderLayout = () => { class={[ { 'fixed top-0 left-0 z-10': fixedHeader.value, - 'w-[calc(100%-var(--left-menu-min-width))] left-[var(--left-menu-min-width)]': + 'w-[calc(100%-var(--left-menu-min-width))] !left-[var(--left-menu-min-width)]': collapse.value && fixedHeader.value && !mobile.value, - 'w-[calc(100%-var(--left-menu-max-width))] left-[var(--left-menu-max-width)]': + 'w-[calc(100%-var(--left-menu-max-width))] !left-[var(--left-menu-max-width)]': !collapse.value && fixedHeader.value && !mobile.value, '!w-full !left-0': mobile.value } ]} style="transition: all var(--transition-time-02);" > - <ToolHeader class="border-bottom-1 border-solid border-[var(--top-tool-border-color)] bg-[var(--top-header-bg-color)] dark:border-[var(--el-border-color)]"></ToolHeader> + <ToolHeader + class={[ + 'bg-[var(--top-header-bg-color)]', + { + 'layout-border__bottom': !tagsView.value + } + ]} + ></ToolHeader> {tagsView.value ? ( - <TagsView class="border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)] dark:border-[var(--el-border-color)]"></TagsView> + <TagsView class="layout-border__bottom layout-border__top"></TagsView> ) : undefined} </div> @@ -109,13 +121,13 @@ export const useRenderLayout = () => { const renderTopLeft = () => { return ( <> - <div class="flex items-center bg-[var(--top-header-bg-color)] border-bottom-1 border-solid border-[var(--top-tool-border-color)] dark:border-[var(--el-border-color)]"> - {logo.value ? <Logo class="hover-trigger !pr-15px"></Logo> : undefined} + <div class="flex items-center bg-[var(--top-header-bg-color)] relative layout-border__bottom dark:bg-[var(--el-bg-color)]"> + {logo.value ? <Logo class="custom-hover"></Logo> : undefined} <ToolHeader class="flex-1"></ToolHeader> </div> <div class="absolute top-[var(--logo-height)+1px] left-0 w-full h-[calc(100%-1px-var(--logo-height))] flex"> - <Menu class="!h-full"></Menu> + <Menu class="!h-full relative layout-border__right"></Menu> <div class={[ `${prefixCls}-content`, @@ -142,12 +154,12 @@ export const useRenderLayout = () => { {tagsView.value ? ( <TagsView class={[ - 'border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)] dark:border-[var(--el-border-color)]', + 'layout-border__bottom absolute', { '!fixed top-0 left-0 z-10': fixedHeader.value, - 'w-[calc(100%-var(--left-menu-min-width))] left-[var(--left-menu-min-width)] mt-[var(--logo-height)]': + 'w-[calc(100%-var(--left-menu-min-width))] !left-[var(--left-menu-min-width)] mt-[calc(var(--logo-height)+1px)]': collapse.value && fixedHeader.value, - 'w-[calc(100%-var(--left-menu-max-width))] left-[var(--left-menu-max-width)] mt-[var(--logo-height)]': + 'w-[calc(100%-var(--left-menu-max-width))] !left-[var(--left-menu-max-width)] mt-[calc(var(--logo-height)+1px)]': !collapse.value && fixedHeader.value } ]} @@ -166,12 +178,28 @@ export const useRenderLayout = () => { const renderTop = () => { return ( <> - <div class="flex items-center justify-between bg-[var(--top-header-bg-color)] border-bottom-1 border-solid border-[var(--top-tool-border-color)] dark:border-[var(--el-border-color)]"> - {logo.value ? <Logo class="hover-trigger"></Logo> : undefined} + <div + class={[ + 'flex items-center justify-between bg-[var(--top-header-bg-color)] relative', + { + 'layout-border__bottom': !tagsView.value + } + ]} + > + {logo.value ? <Logo class="custom-hover"></Logo> : undefined} <Menu class="flex-1 px-10px h-[var(--top-tool-height)]"></Menu> <ToolHeader></ToolHeader> </div> - <div class={[`${prefixCls}-content`, 'h-full w-full']}> + <div + class={[ + `${prefixCls}-content`, + 'w-full', + { + 'h-[calc(100%-var(--app-footer-height))]': !fixedHeader.value, + 'h-[calc(100%-var(--tags-view-height)-var(--app-footer-height))]': fixedHeader.value + } + ]} + > <ElScrollbar v-loading={pageLoading.value} class={[ @@ -186,9 +214,9 @@ export const useRenderLayout = () => { {tagsView.value ? ( <TagsView class={[ - 'border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)] dark:border-[var(--el-border-color)]', + 'layout-border__bottom layout-border__top relative', { - '!fixed w-full top-[var(--top-tool-height)] left-0': fixedHeader.value + '!fixed w-full top-[calc(var(--top-tool-height)+1px)] left-0': fixedHeader.value } ]} style="transition: width var(--transition-time-02), left var(--transition-time-02);" @@ -205,12 +233,12 @@ export const useRenderLayout = () => { const renderCutMenu = () => { return ( <> - <div class="flex items-center bg-[var(--top-header-bg-color)] border-bottom-1 border-solid border-[var(--top-tool-border-color)] dark:border-[var(--el-border-color)]"> - {logo.value ? <Logo class="hover-trigger !pr-15px"></Logo> : undefined} + <div class="flex items-center bg-[var(--top-header-bg-color)] relative layout-border__bottom"> + {logo.value ? <Logo class="custom-hover !pr-15px"></Logo> : undefined} <ToolHeader class="flex-1"></ToolHeader> </div> - <div class="absolute top-[var(--logo-height)] left-0 w-full h-[calc(100%-var(--logo-height))] flex"> + <div class="absolute top-[var(--logo-height)] left-0 w-[calc(100%-2px)] h-[calc(100%-var(--logo-height))] flex"> <TabMenu></TabMenu> <div class={[ @@ -242,18 +270,18 @@ export const useRenderLayout = () => { {tagsView.value ? ( <TagsView class={[ - 'border-bottom-1 border-top-1 border-solid border-[var(--tags-view-border-color)] dark:border-[var(--el-border-color)]', + 'relative layout-border__bottom layout-border__top', { '!fixed top-0 left-0 z-10': fixedHeader.value, - 'w-[calc(100%-var(--tab-menu-min-width))] left-[var(--tab-menu-min-width)] mt-[var(--logo-height)]': + 'w-[calc(100%-var(--tab-menu-min-width))] !left-[var(--tab-menu-min-width)] mt-[var(--logo-height)]': collapse.value && fixedHeader.value, - 'w-[calc(100%-var(--tab-menu-max-width))] left-[var(--tab-menu-max-width)] mt-[var(--logo-height)]': + 'w-[calc(100%-var(--tab-menu-max-width))] !left-[var(--tab-menu-max-width)] mt-[var(--logo-height)]': !collapse.value && fixedHeader.value, - '!fixed top-0 left-[var(--tab-menu-min-width)+var(--left-menu-max-width)] z-10': + '!fixed top-0 !left-[var(--tab-menu-min-width)+var(--left-menu-max-width)] z-10': fixedHeader.value && fixedMenu.value, - 'w-[calc(100%-var(--tab-menu-min-width)-var(--left-menu-max-width))] left-[var(--tab-menu-min-width)+var(--left-menu-max-width)] mt-[var(--logo-height)]': + 'w-[calc(100%-var(--tab-menu-min-width)-var(--left-menu-max-width))] !left-[var(--tab-menu-min-width)+var(--left-menu-max-width)] mt-[var(--logo-height)]': collapse.value && fixedHeader.value && fixedMenu.value, - 'w-[calc(100%-var(--tab-menu-max-width)-var(--left-menu-max-width))] left-[var(--tab-menu-max-width)+var(--left-menu-max-width)] mt-[var(--logo-height)]': + 'w-[calc(100%-var(--tab-menu-max-width)-var(--left-menu-max-width))] !left-[var(--tab-menu-max-width)+var(--left-menu-max-width)] mt-[var(--logo-height)]': !collapse.value && fixedHeader.value && fixedMenu.value } ]} diff --git a/src/main.ts b/src/main.ts index 7fb836f7..3ffbcaa9 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,5 @@ // 引入windi css -import '@/plugins/windi.css' +import '@/plugins/unocss' // 导入全局的svg图标 import '@/plugins/svgIcon' diff --git a/src/plugins/unocss/index.ts b/src/plugins/unocss/index.ts new file mode 100644 index 00000000..d366b5a2 --- /dev/null +++ b/src/plugins/unocss/index.ts @@ -0,0 +1 @@ +import 'virtual:uno.css' diff --git a/src/plugins/windi.css/index.ts b/src/plugins/windi.css/index.ts deleted file mode 100644 index dbdfbbf2..00000000 --- a/src/plugins/windi.css/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -import 'virtual:windi.css' - -import 'virtual:windi-devtools' diff --git a/src/styles/var.css b/src/styles/var.css index d0badc16..a44f804f 100644 --- a/src/styles/var.css +++ b/src/styles/var.css @@ -1,8 +1,5 @@ :root { - --dark-bg-color: #293146; - - /* left menu start */ - --left-menu-border-color: '#eee'; + --login-bg-color: #293146; --left-menu-max-width: 200px; @@ -25,8 +22,6 @@ --logo-height: 50px; --logo-title-text-color: #fff; - - --logo-border-color: 'inherit'; /* logo end */ /* header start */ @@ -40,11 +35,7 @@ --top-tool-p-x: 0; - --top-tool-border-color: #eee; - --tags-view-height: 35px; - - --tags-view-border-color: #eee; /* header start */ /* tab menu start */ @@ -53,8 +44,6 @@ --tab-menu-min-width: 30px; --tab-menu-collapse-height: 36px; - - --tab-menu-border-color: #eee; /* tab menu end */ --app-content-padding: 20px; @@ -66,6 +55,10 @@ --transition-time-02: 0.2s; } +.dark { + --app-content-bg-color: var(--el-bg-color); +} + html, body { -webkit-font-smoothing: antialiased; diff --git a/src/views/Home/Index.vue b/src/views/Home/Index.vue index dfa3b611..6a369263 100644 --- a/src/views/Home/Index.vue +++ b/src/views/Home/Index.vue @@ -7,7 +7,7 @@ <div class="flex items-center"> <img :src="avatar" alt="" class="w-70px h-70px rounded-[50%] mr-20px" /> <div> - <div class="text-20px text-700"> + <div class="text-20px"> {{ t('workplace.welcome') }} {{ username }} {{ t('workplace.happyDay') }} </div> <div class="mt-10px text-14px text-gray-500"> @@ -17,7 +17,7 @@ </div> </el-col> <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24"> - <div class="flex h-70px items-center justify-end <sm:mt-10px"> + <div class="flex h-70px items-center justify-end lt-sm:mt-10px"> <div class="px-8px text-right"> <div class="text-14px text-gray-400 mb-20px">{{ t('workplace.project') }}</div> <CountTo diff --git a/src/views/Login/Login.vue b/src/views/Login/Login.vue index 1ecbec7e..9d5ea20e 100644 --- a/src/views/Login/Login.vue +++ b/src/views/Login/Login.vue @@ -1,11 +1,11 @@ <template> <div :class="prefixCls" - class="h-[100%] relative <xl:bg-v-dark <sm:px-10px <xl:px-10px <md:px-10px" + class="h-[100%] relative lt-xl:bg-[var(--login-bg-color)] lt-sm:px-10px lt-xl:px-10px lt-md:px-10px" > <div class="relative h-full flex mx-auto"> <div - :class="`${prefixCls}__left flex-1 bg-gray-500 bg-opacity-20 relative p-30px <xl:hidden`" + :class="`${prefixCls}__left flex-1 bg-gray-500 bg-opacity-20 relative p-30px lt-xl:hidden`" > <!-- 左上角的 logo + 系统标题 --> <div class="flex items-center relative text-white"> @@ -27,33 +27,35 @@ </TransitionGroup> </div> </div> - <div class="flex-1 p-30px <sm:p-10px dark:bg-v-dark relative"> + <div class="flex-1 p-30px lt-sm:p-10px dark:bg-[var(--login-bg-color)] relative"> <!-- 右上角的主题、语言选择 --> - <div class="flex justify-between items-center text-white @2xl:justify-end @xl:justify-end"> - <div class="flex items-center @2xl:hidden @xl:hidden"> + <div + class="flex justify-between items-center text-white at-2xl:justify-end at-xl:justify-end" + > + <div class="flex items-center at-2xl:hidden at-xl:hidden"> <img alt="" class="w-48px h-48px mr-10px" src="@/assets/imgs/logo.png" /> <span class="text-20px font-bold">{{ underlineToHump(appStore.getTitle) }}</span> </div> <div class="flex justify-end items-center space-x-10px"> <ThemeSwitch /> - <LocaleDropdown class="<xl:text-white dark:text-white" /> + <LocaleDropdown class="lt-xl:text-white dark:text-white" /> </div> </div> <!-- 右边的登录界面 --> <Transition appear enter-active-class="animate__animated animate__bounceInRight"> <div - class="h-full flex items-center m-auto w-[100%] @2xl:max-w-500px @xl:max-w-500px @md:max-w-500px @lg:max-w-500px" + class="h-full flex items-center m-auto w-[100%] at-2xl:max-w-500px at-xl:max-w-500px at-md:max-w-500px at-lg:max-w-500px" > <!-- 账号登录 --> - <LoginForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" /> + <LoginForm class="p-20px h-auto m-auto lt-xl:(rounded-3xl light:bg-white)" /> <!-- 手机登录 --> - <MobileForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" /> + <MobileForm class="p-20px h-auto m-auto lt-xl:(rounded-3xl light:bg-white)" /> <!-- 二维码登录 --> - <QrCodeForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" /> + <QrCodeForm class="p-20px h-auto m-auto lt-xl:(rounded-3xl light:bg-white)" /> <!-- 注册 --> - <RegisterForm class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" /> + <RegisterForm class="p-20px h-auto m-auto lt-xl:(rounded-3xl light:bg-white)" /> <!-- 三方登录 --> - <SSOLoginVue class="p-20px h-auto m-auto <xl:(rounded-3xl light:bg-white)" /> + <SSOLoginVue class="p-20px h-auto m-auto lt-xl:(rounded-3xl light:bg-white)" /> </div> </Transition> </div> @@ -82,6 +84,8 @@ const prefixCls = getPrefixCls('login') $prefix-cls: #{$namespace}-login; .#{$prefix-cls} { + overflow: auto; + &__left { &::before { position: absolute; diff --git a/tsconfig.json b/tsconfig.json index b97c7079..d2909a8a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,7 +10,7 @@ "resolveJsonModule": true, "esModuleInterop": true, "lib": ["esnext", "dom"], - "baseUrl": ".", + "baseUrl": "./", "allowJs": true, "forceConsistentCasingInFileNames": true, "allowSyntheticDefaultImports": true, @@ -36,7 +36,7 @@ "typeRoots": ["./node_modules/@types/", "./types"] }, "include": [ - "src/**/*", + "src", "types/**/*.d.ts", "src/types/auto-imports.d.ts", "src/types/auto-components.d.ts" diff --git a/uno.config.ts b/uno.config.ts new file mode 100644 index 00000000..0645fe68 --- /dev/null +++ b/uno.config.ts @@ -0,0 +1,105 @@ +import { defineConfig, toEscapedSelector as e, presetUno } from 'unocss' +import transformerVariantGroup from '@unocss/transformer-variant-group' + +export default defineConfig({ + // ...UnoCSS options + rules: [ + [ + /^custom-hover$/, + ([], { rawSelector }) => { + const selector = e(rawSelector) + return ` +${selector} { + display: flex; + height: 100%; + padding: 1px 10px 0; + cursor: pointer; + align-items: center; + transition: background var(--transition-time-02); +} +/* you can have multiple rules */ +${selector}:hover { + background-color: var(--top-header-hover-color); +} +.dark ${selector}:hover { + background-color: var(--el-bg-color-overlay); +} +` + } + ], + [ + /^layout-border__left$/, + ([], { rawSelector }) => { + const selector = e(rawSelector) + return ` +${selector}:before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 1px; + height: 100%; + background-color: var(--el-border-color); + z-index: 3; +} +` + } + ], + [ + /^layout-border__right$/, + ([], { rawSelector }) => { + const selector = e(rawSelector) + return ` +${selector}:after { + content: ""; + position: absolute; + top: 0; + right: 0; + width: 1px; + height: 100%; + background-color: var(--el-border-color); + z-index: 3; +} +` + } + ], + [ + /^layout-border__top$/, + ([], { rawSelector }) => { + const selector = e(rawSelector) + return ` +${selector}:before { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 1px; + background-color: var(--el-border-color); + z-index: 3; +} +` + } + ], + [ + /^layout-border__bottom$/, + ([], { rawSelector }) => { + const selector = e(rawSelector) + return ` +${selector}:after { + content: ""; + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 1px; + background-color: var(--el-border-color); + z-index: 3; +} +` + } + ] + ], + presets: [presetUno({ dark: 'class', attributify: false })], + transformers: [transformerVariantGroup()] +}) diff --git a/windi.config.ts b/windi.config.ts deleted file mode 100644 index cf32f975..00000000 --- a/windi.config.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { defineConfig } from 'vite-plugin-windicss' -import plugin from 'windicss/plugin' - -function range(size, startAt = 1) { - return Array.from(Array(size).keys()).map((i) => i + startAt) -} - -export default defineConfig({ - extract: { - include: ['src/**/*.{vue,html,jsx,tsx}'], - exclude: ['node_modules', '.git'] - }, - darkMode: 'class', - attributify: false, - theme: { - extend: { - backgroundColor: { - // 暗黑背景色 - 'v-dark': 'var(--dark-bg-color)' - } - } - }, - plugins: [ - plugin(({ addComponents }) => { - const obj = {} - range(50).map((i) => { - obj[`.border-top-${i}`] = { - borderTopWidth: `${i}px` - } - obj[`.border-left-${i}`] = { - borderLeftWidth: `${i}px` - } - obj[`.border-right-${i}`] = { - borderRightWidth: `${i}px` - } - obj[`.border-bottom-${i}`] = { - borderBottomWidth: `${i}px` - } - }) - addComponents({ - '.hover-trigger': { - display: 'flex', - height: '100%', - padding: '1px 10px 0', - cursor: 'pointer', - alignItems: 'center', - transition: 'background var(--transition-time-02)', - '&:hover': { - backgroundColor: 'var(--top-header-hover-color)' - } - }, - '.dark .hover-trigger': { - '&:hover': { - backgroundColor: 'var(--el-bg-color-overlay)' - } - }, - ...obj - }) - }) - ] -})