mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-06-07 17:07:19 +08:00
feat: ep theme (#156)
* feat: ep-theme * perf: ep-theme Co-authored-by: lrl <742798240@qq.com>
This commit is contained in:
parent
1b052023b6
commit
955b76f30a
@ -40,6 +40,7 @@
|
||||
"animate.css": "^4.1.1",
|
||||
"axios": "^0.21.1",
|
||||
"cropperjs": "^1.5.11",
|
||||
"css-color-function": "^1.3.3",
|
||||
"dayjs": "^1.10.7",
|
||||
"echarts": "^5.2.1",
|
||||
"element-plus": "1.2.0-beta.6",
|
||||
@ -56,6 +57,7 @@
|
||||
"remixicon": "^2.5.0",
|
||||
"resize-observer-polyfill": "^1.5.1",
|
||||
"responsive-storage": "^1.0.11",
|
||||
"rgb-hex": "^4.0.0",
|
||||
"v-contextmenu": "3.0.0",
|
||||
"vue": "^3.2.24",
|
||||
"vue-i18n": "^9.2.0-beta.3",
|
||||
|
60
pnpm-lock.yaml
generated
60
pnpm-lock.yaml
generated
@ -33,6 +33,7 @@ specifiers:
|
||||
babel-plugin-transform-remove-console: 6.9.4
|
||||
cropperjs: ^1.5.11
|
||||
cross-env: 7.0.3
|
||||
css-color-function: ^1.3.3
|
||||
dayjs: ^1.10.7
|
||||
echarts: ^5.2.1
|
||||
element-plus: 1.2.0-beta.6
|
||||
@ -58,6 +59,7 @@ specifiers:
|
||||
remixicon: ^2.5.0
|
||||
resize-observer-polyfill: ^1.5.1
|
||||
responsive-storage: ^1.0.11
|
||||
rgb-hex: ^4.0.0
|
||||
rimraf: 3.0.2
|
||||
sass: ^1.45.0
|
||||
sass-loader: ^12.3.0
|
||||
@ -98,6 +100,7 @@ dependencies:
|
||||
animate.css: 4.1.1
|
||||
axios: 0.21.4
|
||||
cropperjs: 1.5.12
|
||||
css-color-function: 1.3.3
|
||||
dayjs: 1.10.7
|
||||
echarts: 5.2.2
|
||||
element-plus: 1.2.0-beta.6_vue@3.2.24
|
||||
@ -114,6 +117,7 @@ dependencies:
|
||||
remixicon: 2.5.0
|
||||
resize-observer-polyfill: 1.5.1
|
||||
responsive-storage: 1.0.11_vue@3.2.24
|
||||
rgb-hex: 4.0.0
|
||||
v-contextmenu: 3.0.0_vue@3.2.24
|
||||
vue: 3.2.24
|
||||
vue-i18n: 9.2.0-beta.17_vue@3.2.24
|
||||
@ -1953,6 +1957,10 @@ packages:
|
||||
}
|
||||
dev: true
|
||||
|
||||
/balanced-match/0.1.0:
|
||||
resolution: { integrity: sha1-tQS9BYabOSWd0MXvw12EMXbczEo= }
|
||||
dev: false
|
||||
|
||||
/balanced-match/1.0.2:
|
||||
resolution:
|
||||
{
|
||||
@ -2277,6 +2285,11 @@ packages:
|
||||
is-regexp: 2.1.0
|
||||
dev: true
|
||||
|
||||
/clone/1.0.4:
|
||||
resolution: { integrity: sha1-2jCcwmPfFZlMaIypAheco8fNfH4= }
|
||||
engines: { node: ">=0.8" }
|
||||
dev: false
|
||||
|
||||
/clone/2.1.2:
|
||||
resolution: { integrity: sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= }
|
||||
engines: { node: ">=0.8" }
|
||||
@ -2308,7 +2321,12 @@ packages:
|
||||
{
|
||||
integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/color-string/0.3.0:
|
||||
resolution: { integrity: sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE= }
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
dev: false
|
||||
|
||||
/color-string/1.9.0:
|
||||
resolution:
|
||||
@ -2320,6 +2338,14 @@ packages:
|
||||
simple-swizzle: 0.2.2
|
||||
dev: true
|
||||
|
||||
/color/0.11.4:
|
||||
resolution: { integrity: sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q= }
|
||||
dependencies:
|
||||
clone: 1.0.4
|
||||
color-convert: 1.9.3
|
||||
color-string: 0.3.0
|
||||
dev: false
|
||||
|
||||
/color/4.1.0:
|
||||
resolution:
|
||||
{
|
||||
@ -2527,6 +2553,15 @@ packages:
|
||||
which: 2.0.2
|
||||
dev: true
|
||||
|
||||
/css-color-function/1.3.3:
|
||||
resolution: { integrity: sha1-jtJMLAIFBzM5+voAS8jBQfzLKC4= }
|
||||
dependencies:
|
||||
balanced-match: 0.1.0
|
||||
color: 0.11.4
|
||||
debug: 3.2.7
|
||||
rgb: 0.1.0
|
||||
dev: false
|
||||
|
||||
/css-declaration-sorter/6.1.3_postcss@8.3.11:
|
||||
resolution:
|
||||
{
|
||||
@ -2726,6 +2761,15 @@ packages:
|
||||
ms: 2.0.0
|
||||
dev: true
|
||||
|
||||
/debug/3.2.7:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
|
||||
}
|
||||
dependencies:
|
||||
ms: 2.1.2
|
||||
dev: false
|
||||
|
||||
/debug/4.3.2:
|
||||
resolution:
|
||||
{
|
||||
@ -4986,7 +5030,6 @@ packages:
|
||||
{
|
||||
integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
}
|
||||
dev: true
|
||||
|
||||
/multimatch/4.0.0:
|
||||
resolution:
|
||||
@ -6281,6 +6324,19 @@ packages:
|
||||
engines: { iojs: ">=1.0.0", node: ">=0.10.0" }
|
||||
dev: true
|
||||
|
||||
/rgb-hex/4.0.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-Eg2ev5CiMBnQ9Gpflmqbwbso0CCdISqtVIow7OpYSLN1ULUv2jTB9YieS1DSSn/17AD7KkPWDPzSFzI4GSuu/Q==
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
dev: false
|
||||
|
||||
/rgb/0.1.0:
|
||||
resolution: { integrity: sha1-vieykej+/+rBvZlylyG/pA/AN7U= }
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/rimraf/3.0.2:
|
||||
resolution:
|
||||
{
|
||||
|
@ -9,6 +9,8 @@ import {
|
||||
useCssModule,
|
||||
getCurrentInstance
|
||||
} from "vue";
|
||||
import rgbHex from "rgb-hex";
|
||||
import { find } from "lodash-es";
|
||||
import panel from "../panel/index.vue";
|
||||
import { getConfig } from "/@/config";
|
||||
import { useRouter } from "vue-router";
|
||||
@ -19,8 +21,10 @@ import { debounce } from "/@/utils/debounce";
|
||||
import darkIcon from "/@/assets/svg/dark.svg";
|
||||
import { themeColorsType } from "../../types";
|
||||
import { useAppStoreHook } from "/@/store/modules/app";
|
||||
import { useEpThemeStoreHook } from "/@/store/modules/epTheme";
|
||||
import { storageLocal, storageSession } from "/@/utils/storage";
|
||||
import { useMultiTagsStoreHook } from "/@/store/modules/multiTags";
|
||||
import { createNewStyle, writeNewStyle } from "/@/utils/theme";
|
||||
import { toggleTheme } from "@zougt/vite-plugin-theme-preprocessor/dist/browser-utils";
|
||||
|
||||
const router = useRouter();
|
||||
@ -77,6 +81,8 @@ const markValue = ref(storageLocal.getItem("showModel") || "smart");
|
||||
|
||||
const logoVal = ref(storageLocal.getItem("logoVal") || "1");
|
||||
|
||||
const epThemeColor = ref(useEpThemeStoreHook().getEpThemeColor);
|
||||
|
||||
const settings = reactive({
|
||||
greyVal: instance.sets.grey,
|
||||
weakVal: instance.sets.weak,
|
||||
@ -146,6 +152,8 @@ nextTick(() => {
|
||||
settings.weakVal &&
|
||||
document.querySelector("html")?.setAttribute("class", "html-weakness");
|
||||
settings.tabsVal && tagsChange();
|
||||
|
||||
writeNewStyle(createNewStyle(epThemeColor.value));
|
||||
});
|
||||
|
||||
// 清空缓存并返回登录页
|
||||
@ -167,6 +175,7 @@ function onReset() {
|
||||
}
|
||||
]);
|
||||
useMultiTagsStoreHook().multiTagsCacheChange(getConfig().MultiTagsCache);
|
||||
useEpThemeStoreHook().setEpThemeColor("#409EFF");
|
||||
router.push("/login");
|
||||
}
|
||||
|
||||
@ -236,7 +245,21 @@ function setLayoutThemeColor(theme: string) {
|
||||
scopeName: `layout-theme-${theme}`
|
||||
});
|
||||
instance.layout = { layout: useAppStoreHook().layout, theme };
|
||||
|
||||
if (theme === "default" || theme === "light") {
|
||||
setEpThemeColor("#409EFF");
|
||||
} else {
|
||||
const colors = find(themeColors.value, { themeColor: theme });
|
||||
const color = "#" + rgbHex(colors.rgb);
|
||||
setEpThemeColor(color);
|
||||
}
|
||||
}
|
||||
|
||||
// 设置ep主题色
|
||||
const setEpThemeColor = (color: string) => {
|
||||
writeNewStyle(createNewStyle(color));
|
||||
useEpThemeStoreHook().setEpThemeColor(color);
|
||||
};
|
||||
|
||||
let dataTheme = ref<boolean>(false);
|
||||
|
||||
|
@ -44,6 +44,7 @@ import {
|
||||
ElCollapse,
|
||||
ElCollapseItem,
|
||||
ElTreeV2,
|
||||
ElColorPicker,
|
||||
// 指令
|
||||
ElLoading,
|
||||
ElInfiniteScroll
|
||||
@ -96,7 +97,8 @@ const components = [
|
||||
ElEmpty,
|
||||
ElCollapse,
|
||||
ElCollapseItem,
|
||||
ElTreeV2
|
||||
ElTreeV2,
|
||||
ElColorPicker
|
||||
];
|
||||
|
||||
// https://element-plus.org/zh-CN/component/icon.html
|
||||
|
25
src/store/modules/epTheme.ts
Normal file
25
src/store/modules/epTheme.ts
Normal file
@ -0,0 +1,25 @@
|
||||
import { store } from "/@/store";
|
||||
import { defineStore } from "pinia";
|
||||
import { storageLocal } from "/@/utils/storage";
|
||||
|
||||
export const useEpThemeStore = defineStore({
|
||||
id: "pure-epTheme",
|
||||
state: () => ({
|
||||
epThemeColor: storageLocal.getItem("epThemeColor") || "#409EFF"
|
||||
}),
|
||||
getters: {
|
||||
getEpThemeColor() {
|
||||
return this.epThemeColor;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setEpThemeColor(newColor) {
|
||||
this.epThemeColor = newColor;
|
||||
storageLocal.setItem("epThemeColor", newColor);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export function useEpThemeStoreHook() {
|
||||
return useEpThemeStore(store);
|
||||
}
|
71
src/utils/theme/index.ts
Normal file
71
src/utils/theme/index.ts
Normal file
@ -0,0 +1,71 @@
|
||||
import rgbHex from "rgb-hex";
|
||||
import color from "css-color-function";
|
||||
import epCss from "element-plus/dist/index.css";
|
||||
|
||||
const formula = {
|
||||
"shade-1": "color(primary shade(10%))",
|
||||
"light-1": "color(primary tint(10%))",
|
||||
"light-2": "color(primary tint(20%))",
|
||||
"light-3": "color(primary tint(30%))",
|
||||
"light-4": "color(primary tint(40%))",
|
||||
"light-5": "color(primary tint(50%))",
|
||||
"light-6": "color(primary tint(60%))",
|
||||
"light-7": "color(primary tint(70%))",
|
||||
"light-8": "color(primary tint(80%))",
|
||||
"light-9": "color(primary tint(90%))"
|
||||
};
|
||||
|
||||
export const writeNewStyle = newStyle => {
|
||||
const style = window.document.createElement("style");
|
||||
style.innerText = newStyle;
|
||||
window.document.head.appendChild(style);
|
||||
};
|
||||
|
||||
export const createNewStyle = primaryStyle => {
|
||||
const colors = createColors(primaryStyle);
|
||||
let cssText = getOriginStyle();
|
||||
Object.keys(colors).forEach(key => {
|
||||
cssText = cssText.replace(
|
||||
new RegExp("(:|\\s+)" + key, "g"),
|
||||
"$1" + colors[key]
|
||||
);
|
||||
});
|
||||
return cssText;
|
||||
};
|
||||
|
||||
export const createColors = primary => {
|
||||
if (!primary) return;
|
||||
const colors = {
|
||||
primary
|
||||
};
|
||||
Object.keys(formula).forEach(key => {
|
||||
const value = formula[key].replace(/primary/, primary);
|
||||
colors[key] = "#" + rgbHex(color.convert(value));
|
||||
});
|
||||
return colors;
|
||||
};
|
||||
|
||||
export const getOriginStyle = () => {
|
||||
return getStyleTemplate(epCss);
|
||||
};
|
||||
|
||||
const getStyleTemplate = data => {
|
||||
const colorMap = {
|
||||
"#3a8ee6": "shade-1",
|
||||
"#409eff": "primary",
|
||||
"#53a8ff": "light-1",
|
||||
"#66b1ff": "light-2",
|
||||
"#79bbff": "light-3",
|
||||
"#8cc5ff": "light-4",
|
||||
"#a0cfff": "light-5",
|
||||
"#b3d8ff": "light-6",
|
||||
"#c6e2ff": "light-7",
|
||||
"#d9ecff": "light-8",
|
||||
"#ecf5ff": "light-9"
|
||||
};
|
||||
Object.keys(colorMap).forEach(key => {
|
||||
const value = colorMap[key];
|
||||
data = data.replace(new RegExp(key, "ig"), value);
|
||||
});
|
||||
return data;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user