refactor: theme

This commit is contained in:
xiaoxian521
2021-10-27 09:03:12 +08:00
parent 25c37bb2fa
commit fc4bfc35d7
12 changed files with 288 additions and 348 deletions

View File

@@ -1,5 +1,4 @@
<script setup lang="ts">
import { split } from "lodash-es";
import panel from "../panel/index.vue";
import { useRouter } from "vue-router";
import { emitter } from "/@/utils/mitt";
@@ -99,36 +98,20 @@ function onChange({ label }) {
emitter.emit("tagViewsShowModel", label);
}
const verticalDarkDom = templateRef<HTMLElement | null>(
"verticalDarkDom",
null
);
const verticalLightDom = templateRef<HTMLElement | null>(
"verticalLightDom",
null
);
const horizontalDarkDom = templateRef<HTMLElement | null>(
"horizontalDarkDom",
null
);
const horizontalLightDom = templateRef<HTMLElement | null>(
"horizontalLightDom",
null
);
const verticalRef = templateRef<HTMLElement | null>("verticalRef", null);
const horizontalRef = templateRef<HTMLElement | null>("horizontalRef", null);
let dataTheme =
ref(storageLocal.getItem("responsive-layout")) ||
ref({
layout: "horizontal-dark"
layout: "vertical"
});
if (unref(dataTheme)) {
// 设置主题
let theme = split(unref(dataTheme).layout, "-")[1];
window.document.body.setAttribute("data-theme", theme);
// 设置导航模式
let layout = split(unref(dataTheme).layout, "-")[0];
window.document.body.setAttribute("data-layout", layout);
let layout = unref(dataTheme).layout;
window.document.body.setAttribute("layout", layout);
}
// 侧边栏Logo
@@ -147,42 +130,21 @@ function setFalse(Doms): any {
watch(instance, ({ layout }) => {
switch (layout["layout"]) {
case "vertical-dark":
toggleClass(true, isSelect, unref(verticalDarkDom));
debounce(
setFalse([verticalLightDom, horizontalDarkDom, horizontalLightDom]),
50
);
case "vertical":
toggleClass(true, isSelect, unref(verticalRef));
debounce(setFalse([horizontalRef]), 50);
break;
case "vertical-light":
toggleClass(true, isSelect, unref(verticalLightDom));
debounce(
setFalse([verticalDarkDom, horizontalDarkDom, horizontalLightDom]),
50
);
break;
case "horizontal-dark":
toggleClass(true, isSelect, unref(horizontalDarkDom));
debounce(
setFalse([verticalDarkDom, verticalLightDom, horizontalLightDom]),
50
);
break;
case "horizontal-light":
toggleClass(true, isSelect, unref(horizontalLightDom));
debounce(
setFalse([verticalDarkDom, verticalLightDom, horizontalDarkDom]),
50
);
case "horizontal":
toggleClass(true, isSelect, unref(horizontalRef));
debounce(setFalse([verticalRef]), 50);
break;
}
});
function setTheme(layout: string, theme: string) {
dataTheme.value.layout = `${layout}-${theme}`;
window.document.body.setAttribute("data-layout", layout);
window.document.body.setAttribute("data-theme", theme);
instance.layout = { layout: `${layout}-${theme}` };
function setTheme(layout: string) {
dataTheme.value.layout = `${layout}`;
window.document.body.setAttribute("layout", layout);
instance.layout = { layout: `${layout}` };
useAppStoreHook().setLayout(layout);
}
</script>
@@ -190,23 +152,12 @@ function setTheme(layout: string, theme: string) {
<template>
<panel>
<el-divider>主题风格</el-divider>
<ul class="theme-stley">
<ul class="pure-theme">
<el-tooltip class="item" content="左侧菜单暗色模式" placement="bottom">
<li
:class="dataTheme.layout === 'vertical-dark' ? $style.isSelect : ''"
ref="verticalDarkDom"
@click="setTheme('vertical', 'dark')"
>
<div></div>
<div></div>
</li>
</el-tooltip>
<el-tooltip class="item" content="左侧菜单亮色模式" placement="bottom">
<li
:class="dataTheme.layout === 'vertical-light' ? $style.isSelect : ''"
ref="verticalLightDom"
@click="setTheme('vertical', 'light')"
:class="dataTheme.layout === 'vertical' ? $style.isSelect : ''"
ref="verticalRef"
@click="setTheme('vertical')"
>
<div></div>
<div></div>
@@ -215,27 +166,19 @@ function setTheme(layout: string, theme: string) {
<el-tooltip class="item" content="顶部菜单暗色模式" placement="bottom">
<li
:class="dataTheme.layout === 'horizontal-dark' ? $style.isSelect : ''"
ref="horizontalDarkDom"
@click="setTheme('horizontal', 'dark')"
:class="dataTheme.layout === 'horizontal' ? $style.isSelect : ''"
ref="horizontalRef"
@click="setTheme('horizontal')"
>
<div></div>
<div></div>
</li>
</el-tooltip>
</ul>
<el-tooltip class="item" content="顶部菜单亮色模式" placement="bottom">
<li
:class="
dataTheme.layout === 'horizontal-light' ? $style.isSelect : ''
"
ref="horizontalLightDom"
@click="setTheme('horizontal', 'light')"
>
<div></div>
<div></div>
</li>
</el-tooltip>
<el-divider>主题色</el-divider>
<ul>
<li>11</li>
</ul>
<el-divider>界面显示</el-divider>
@@ -322,10 +265,10 @@ function setTheme(layout: string, theme: string) {
font-weight: 700;
}
.theme-stley {
.pure-theme {
margin-top: 25px;
width: 100%;
height: 180px;
height: 100px;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
@@ -362,28 +305,6 @@ function setTheme(layout: string, theme: string) {
}
&:nth-child(2) {
div {
&:nth-child(1) {
width: 30%;
height: 100%;
box-shadow: 0 0 1px #888;
background: #fff;
border-radius: 4px 0 0 4px;
}
&:nth-child(2) {
width: 70%;
height: 30%;
top: 0;
right: 0;
background: #fff;
box-shadow: 0 0 1px #888;
position: absolute;
}
}
}
&:nth-child(3) {
div {
&:nth-child(1) {
width: 100%;
@@ -393,17 +314,6 @@ function setTheme(layout: string, theme: string) {
}
}
}
&:nth-child(4) {
div {
&:nth-child(1) {
width: 100%;
height: 30%;
background: #fff;
box-shadow: 0 0 1px #888;
}
}
}
}
}
</style>

View File

@@ -16,7 +16,6 @@ import { useI18n } from "vue-i18n";
import { routerArrays } from "./types";
import { emitter } from "/@/utils/mitt";
import { useEventListener } from "@vueuse/core";
import { storageLocal } from "/@/utils/storage";
import { useAppStoreHook } from "/@/store/modules/app";
import fullScreen from "/@/assets/svg/full_screen.svg";
import exitScreen from "/@/assets/svg/exit_screen.svg";
@@ -83,11 +82,8 @@ const handleClickOutside = (params: boolean) => {
};
function setTheme(layoutModel: string) {
let { layout } = storageLocal.getItem("responsive-layout");
let theme = layout.match(/-(.*)/)[1];
window.document.body.setAttribute("data-layout", layoutModel);
window.document.body.setAttribute("data-theme", theme);
instance.layout = { layout: `${layoutModel}-${theme}` };
window.document.body.setAttribute("layout", layoutModel);
instance.layout = { layout: `${layoutModel}` };
}
// 监听容器

View File

@@ -0,0 +1,17 @@
/**
*此scss变量文件作为multipleScopeVars去编译时会自动移除!default以达到变量提升
*同时此scss变量文件作为默认主题变量文件被其他.scss通过 @import 时,必需 !default
*/
// 菜单选中后字体样式
$subMenuActiveText: #f4f4f5 !default;
//菜单背景
$menuBg: #1b2a47 !default;
// 鼠标覆盖菜单时的背景
$menuHover: #2a395b !default;
// 子菜单背景
$subMenuBg: #1f2d3d !default;
// 鼠标覆盖子菜单时的背景
$subMenuHover: #001528 !default;
$navTextColor: #fff !default;
$menuText: #7a80b4;

19
src/layout/theme/index.ts Normal file
View File

@@ -0,0 +1,19 @@
export const toggleTheme = (scopeName = "theme-default") => {
let styleLink: any = document.getElementById("theme-button");
if (styleLink) {
// 假如存在id为theme-button 的link标签直接修改其href
styleLink.href = `/${scopeName}.css`;
// 注如果是removeCssScopeName:true移除了主题文件的权重类名就可以不用修改className 操作
document.documentElement.className = scopeName;
} else {
// 不存在的话,则新建一个
styleLink = document.createElement("link");
styleLink.type = "text/css";
styleLink.rel = "stylesheet";
styleLink.id = "theme-button";
styleLink.href = `/${scopeName}.css`;
// 注如果是removeCssScopeName:true移除了主题文件的权重类名就可以不用修改className 操作
document.documentElement.className = scopeName;
document.head.append(styleLink);
}
};

View File

@@ -0,0 +1,7 @@
$subMenuActiveText: #409eff;
$menuBg: #fff;
$menuHover: #e0ebf6;
$subMenuBg: #fff;
$subMenuHover: #e0ebf6;
$navTextColor: #7a80b4;
$menuText: #7a80b4;

View File

@@ -37,6 +37,9 @@ import {
ElBacktop
} from "element-plus";
// https://element-plus.org/zh-CN/component/icon.html
import { Menu } from "@element-plus/icons";
const components = [
ElTag,
ElAffix,
@@ -71,7 +74,8 @@ const components = [
ElRadioGroup,
ElDescriptions,
ElDescriptionsItem,
ElBacktop
ElBacktop,
Menu
];
const plugins = [ElLoading];

View File

@@ -21,9 +21,7 @@ export const useAppStore = defineStore({
: true,
withoutAnimation: false
},
layout:
storageLocal.getItem("responsive-layout")?.layout.match(/(.*)-/)[1] ??
"vertical",
layout: storageLocal.getItem("responsive-layout")?.layout ?? "vertical",
device: deviceDetection() ? "mobile" : "desktop"
}),
getters: {

View File

@@ -1,17 +1,8 @@
@import "../layout/theme/default-vars.scss";
@mixin merge-style(
// 菜单选中后字体样式
$subMenuActiveText,
//菜单背景
$menuBg,
// 鼠标覆盖菜单时的背景
$menuHover,
// 子菜单背景
$subMenuBg,
// 鼠标覆盖子菜单时的背景
$subMenuHover,
// vertical模式下主体内容距离网页文档左侧的距离
$sideBarWidth,
$navTextColor
$sideBarWidth
) {
$menuText: #7a80b4;
$menuActiveText: #7a80b4;
@@ -72,7 +63,7 @@
.sidebar-container {
transition: width 0.28s;
width: $sideBarWidth;
width: $sideBarWidth !important;
background-color: $menuBg;
height: 100%;
position: fixed;
@@ -211,14 +202,14 @@
display: flex;
min-width: 280px;
align-items: center;
color: $navTextColor;
color: $navTextColor !important;
justify-content: flex-end;
.screen-full {
cursor: pointer;
&:hover {
background: $menuHover;
background: $menuHover !important;
}
}
@@ -282,13 +273,13 @@
.el-menu-item,
.el-sub-menu__title {
color: $menuText;
color: $menuText !important;
}
.submenu-title-noDropdown,
.el-sub-menu__title {
height: 60px;
background: $menuBg;
background: $menuBg !important;
&:hover {
background-color: $menuHover !important;
@@ -529,7 +520,7 @@
}
.main-container {
margin-left: 0 !important;
margin-left: 0;
}
.sidebar-container {
@@ -554,10 +545,13 @@
}
}
body[data-layout="vertical"] {
body[layout="vertical"] {
$sideBarWidth: 210px;
@include merge-style($sideBarWidth);
.hideSidebar {
.fixed-header {
width: calc(100% - 54px) !important;
width: calc(100% - 54px);
transition: width 0.28s;
}
@@ -566,7 +560,7 @@ body[data-layout="vertical"] {
}
.main-container {
margin-left: 54px !important;
margin-left: 0 !important;
}
.submenu-title-noDropdown {
@@ -605,36 +599,39 @@ body[data-layout="vertical"] {
}
}
body[data-layout="horizontal"] {
body[layout="horizontal"] {
$sideBarWidth: 0;
@include merge-style($sideBarWidth);
.fixed-header {
width: 100% !important;
width: 100%;
transition: none !important;
}
}
// vertical模式下不隐藏标签页
body[data-layout="vertical"][data-show-tag="false"] {
body[layout="vertical"][data-show-tag="false"] {
.fixed-header + .app-main {
padding-top: 85px;
}
}
// vertical模式下隐藏标签页
body[data-layout="vertical"][data-show-tag="true"] {
body[layout="vertical"][data-show-tag="true"] {
.fixed-header + .app-main {
padding-top: 48px;
}
}
// horizontal模式下不隐藏标签页
body[data-layout="horizontal"][data-show-tag="false"] {
body[layout="horizontal"][data-show-tag="false"] {
.fixed-header + .app-main {
padding-top: 98px;
}
}
// horizontal模式下隐藏标签页
body[data-layout="horizontal"][data-show-tag="true"] {
body[layout="horizontal"][data-show-tag="true"] {
.fixed-header {
box-shadow: 0 1px 4px rgb(0 21 41 / 8%);
}
@@ -643,87 +640,3 @@ body[data-layout="horizontal"][data-show-tag="true"] {
padding-top: 62px;
}
}
// vertical模式下暗色主题
body[data-layout="vertical"][data-theme="dark"] {
$subMenuActiveText: #f4f4f5;
$menuBg: #1b2a47;
$menuHover: #2a395b;
$subMenuBg: #1f2d3d;
$subMenuHover: #001528;
$sideBarWidth: 210px;
$navTextColor: #fff;
@include merge-style(
$subMenuActiveText,
$menuBg,
$menuHover,
$subMenuBg,
$subMenuHover,
$sideBarWidth,
$navTextColor
);
}
// vertical模式下亮色主题
body[data-layout="vertical"][data-theme="light"] {
$subMenuActiveText: #409eff;
$menuBg: #fff;
$menuHover: #e0ebf6;
$subMenuBg: #fff;
$subMenuHover: #e0ebf6;
$sideBarWidth: 210px;
$navTextColor: #7a80b4;
@include merge-style(
$subMenuActiveText,
$menuBg,
$menuHover,
$subMenuBg,
$subMenuHover,
$sideBarWidth,
$navTextColor
);
}
// horizontal模式下暗色主题
body[data-layout="horizontal"][data-theme="dark"] {
$subMenuActiveText: #f4f4f5;
$menuBg: #1b2a47;
$menuHover: #2a395b;
$subMenuBg: #1f2d3d;
$subMenuHover: #001528;
$sideBarWidth: 0;
$navTextColor: #fff;
@include merge-style(
$subMenuActiveText,
$menuBg,
$menuHover,
$subMenuBg,
$subMenuHover,
$sideBarWidth,
$navTextColor
);
}
// horizontal模式下亮色主题
body[data-layout="horizontal"][data-theme="light"] {
$subMenuActiveText: #409eff;
$menuBg: #fff;
$menuHover: #e0ebf6;
$subMenuBg: #fff;
$subMenuHover: #e0ebf6;
$sideBarWidth: 0;
$navTextColor: #7a80b4;
@include merge-style(
$subMenuActiveText,
$menuBg,
$menuHover,
$subMenuBg,
$subMenuHover,
$sideBarWidth,
$navTextColor
);
}