mirror of
https://github.com/m-xlsea/ruoyi-plus-soybean.git
synced 2025-09-24 07:49:47 +08:00
fix(projects): 修复vertical sider自适应主题
This commit is contained in:
@ -33,8 +33,29 @@ import {
|
||||
} from 'naive-ui';
|
||||
import { AppProviderContent } from '@/components';
|
||||
import { useThemeStore } from '@/store';
|
||||
import { addColorAlpha } from '@/utils';
|
||||
|
||||
const theme = useThemeStore();
|
||||
const dark = computed(() => (theme.darkMode ? darkTheme : undefined));
|
||||
|
||||
const primary = computed(() => theme.themeColor);
|
||||
const primaryWithAlpha = computed(() => {
|
||||
const alpha = theme.darkMode ? 0.15 : 0.1;
|
||||
return addColorAlpha(primary.value, alpha);
|
||||
});
|
||||
</script>
|
||||
<style scoped></style>
|
||||
<style>
|
||||
/* 全局与主题颜色相关 */
|
||||
.g_text-primary {
|
||||
color: v-bind(primary);
|
||||
}
|
||||
.g_bg-primary {
|
||||
background-color: v-bind(primary);
|
||||
}
|
||||
.g_bg-primary_active {
|
||||
background-color: v-bind(primaryWithAlpha);
|
||||
}
|
||||
.g_border-primary {
|
||||
border-color: v-bind(primary);
|
||||
}
|
||||
</style>
|
||||
|
@ -20,7 +20,7 @@
|
||||
<slot></slot>
|
||||
</span>
|
||||
<div v-if="closable" class="pl-10px">
|
||||
<icon-close :is-primary="active || isHover" :primary-color="primaryColor" @click="handleClose" />
|
||||
<icon-close :is-primary="isActive || isHover" :primary-color="primaryColor" @click="handleClose" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -32,7 +32,7 @@ import { IconClose } from '@/components';
|
||||
import { shallowColor } from '@/utils';
|
||||
|
||||
const props = defineProps({
|
||||
active: {
|
||||
isActive: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
@ -43,6 +43,10 @@ const props = defineProps({
|
||||
closable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
darkMode: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
const emit = defineEmits(['close']);
|
||||
@ -56,11 +60,12 @@ function handleClose(e: MouseEvent) {
|
||||
|
||||
const buttonStyle = computed(() => {
|
||||
const style: { [key: string]: string } = {};
|
||||
if (props.active || isHover.value) {
|
||||
if (props.isActive || isHover.value) {
|
||||
style.color = props.primaryColor;
|
||||
style.borderColor = shallowColor(props.primaryColor, 0.3);
|
||||
if (props.active) {
|
||||
style.backgroundColor = shallowColor(props.primaryColor, 0.1);
|
||||
if (props.isActive) {
|
||||
const alpha = props.darkMode ? 0.15 : 0.1;
|
||||
style.backgroundColor = shallowColor(props.primaryColor, alpha);
|
||||
}
|
||||
}
|
||||
return style;
|
||||
|
@ -11,11 +11,16 @@
|
||||
<rect width="100%" height="100%" x="0"></rect>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<!-- 修改为50%防止重叠颜色不一致 -->
|
||||
<svg width="50%" height="100%">
|
||||
<use xlink:href="#geometry-left" width="214" height="36" :fill="foregorund"></use>
|
||||
</svg>
|
||||
<svg width="50%" height="100%">
|
||||
<use xlink:href="#geometry-left" width="214" height="36" :fill="fill"></use>
|
||||
</svg>
|
||||
<g transform="scale(-1, 1)">
|
||||
<svg width="50%" height="100%" x="-100%" y="0">
|
||||
<use xlink:href="#geometry-right" width="214" height="36" :fill="foregorund"></use>
|
||||
</svg>
|
||||
<svg width="50%" height="100%" x="-100%" y="0">
|
||||
<use xlink:href="#geometry-right" width="214" height="36" :fill="fill"></use>
|
||||
</svg>
|
||||
@ -25,6 +30,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { shallowColor } from '@/utils';
|
||||
|
||||
/** 填充的背景颜色: [默认颜色, 暗黑主题颜色] */
|
||||
type FillColor = [string, string];
|
||||
@ -38,6 +44,10 @@ const props = defineProps({
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
primaryColor: {
|
||||
type: String,
|
||||
default: '#409EFF'
|
||||
},
|
||||
darkMode: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
@ -45,9 +55,9 @@ const props = defineProps({
|
||||
});
|
||||
|
||||
const defaultColor: FillColor = ['#fff', '#18181c'];
|
||||
const activeColor: FillColor = ['#eef6ff', '#1e3044'];
|
||||
const hoverColor: FillColor = ['#dee1e6', '#3f3c37'];
|
||||
|
||||
const foregorund = computed(() => defaultColor[Number(props.darkMode)]);
|
||||
const fill = computed(() => {
|
||||
const index = Number(props.darkMode);
|
||||
let color = defaultColor[index];
|
||||
@ -55,7 +65,8 @@ const fill = computed(() => {
|
||||
color = hoverColor[index];
|
||||
}
|
||||
if (props.isActive) {
|
||||
color = activeColor[index];
|
||||
const alpha = props.darkMode ? 0.15 : 0.1;
|
||||
color = shallowColor(props.primaryColor, alpha);
|
||||
}
|
||||
return color;
|
||||
});
|
||||
|
@ -6,7 +6,13 @@
|
||||
@mouseleave="setFalse"
|
||||
>
|
||||
<div class="absolute-lb w-full h-full overflow-hidden">
|
||||
<svg-radius-bg class="w-full h-full" :is-active="isActive" :is-hover="isHover" :dark-mode="darkMode" />
|
||||
<svg-radius-bg
|
||||
class="w-full h-full"
|
||||
:is-active="isActive"
|
||||
:is-hover="isHover"
|
||||
:dark-mode="darkMode"
|
||||
:primary-color="primaryColor"
|
||||
/>
|
||||
</div>
|
||||
<span class="relative z-2">
|
||||
<slot></slot>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div class="mb-6px px-4px cursor-pointer" @mouseenter="setTrue" @mouseleave="setFalse">
|
||||
<div
|
||||
class="flex-center flex-col py-12px rounded-2px"
|
||||
:class="{ 'text-primary bg-primary bg-opacity-10': isActive, 'text-primary': isHover }"
|
||||
:class="{ 'g_text-primary g_bg-primary_active': isActive, 'g_text-primary': isHover }"
|
||||
>
|
||||
<component :is="icon" :class="[isMini ? 'text-16px' : 'text-20px']" />
|
||||
<p
|
||||
|
@ -10,12 +10,12 @@
|
||||
duration-300
|
||||
ease-in-out
|
||||
bg-white
|
||||
dark:bg-[#18181c]
|
||||
dark:bg-dark
|
||||
"
|
||||
:style="{ width: showDrawer ? theme.menuStyle.width + 'px' : '0px' }"
|
||||
>
|
||||
<header class="header-height flex-y-center justify-between">
|
||||
<h2 class="pl-8px text-16px text-primary font-bold">{{ title }}</h2>
|
||||
<h2 class="pl-8px text-16px g_text-primary font-bold">{{ title }}</h2>
|
||||
<div class="px-8px text-16px text-gray-600 cursor-pointer" @click="toggleFixedMixMenu">
|
||||
<icon-mdi:pin-off v-if="app.menu.fixedMix" />
|
||||
<icon-mdi:pin v-else />
|
||||
|
@ -4,6 +4,7 @@
|
||||
v-for="item in app.multiTab.routes"
|
||||
:key="item.path"
|
||||
:is-active="app.multiTab.activeRoute === item.fullPath"
|
||||
:primary-color="theme.themeColor"
|
||||
:closable="item.name !== ROUTE_HOME.name"
|
||||
:dark-mode="theme.darkMode"
|
||||
@click="handleClickTab(item.fullPath)"
|
||||
@ -18,7 +19,7 @@
|
||||
v-for="item in app.multiTab.routes"
|
||||
:key="item.path"
|
||||
class="mr-10px"
|
||||
:active="app.multiTab.activeRoute === item.fullPath"
|
||||
:is-active="app.multiTab.activeRoute === item.fullPath"
|
||||
:primary-color="theme.themeColor"
|
||||
:closable="item.name !== ROUTE_HOME.name"
|
||||
:dark-mode="theme.darkMode"
|
||||
|
@ -3,10 +3,10 @@
|
||||
<div class="flex-center">
|
||||
<n-switch :value="theme.darkMode" @update:value="handleDarkMode">
|
||||
<template #checked>
|
||||
<icon-mdi-white-balance-sunny class="text-14px text-primary" />
|
||||
<icon-mdi-white-balance-sunny class="text-14px g_text-primary" />
|
||||
</template>
|
||||
<template #unchecked>
|
||||
<icon-mdi-moon-waning-crescent class="text-14px text-primary" />
|
||||
<icon-mdi-moon-waning-crescent class="text-14px g_text-primary" />
|
||||
</template>
|
||||
</n-switch>
|
||||
</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div
|
||||
class="border-2px rounded-6px cursor-pointer hover:border-primary"
|
||||
:class="[checked ? 'border-primary' : 'border-transparent']"
|
||||
class="border-2px rounded-6px cursor-pointer hover:g_border-primary"
|
||||
:class="[checked ? 'g_border-primary' : 'border-transparent']"
|
||||
>
|
||||
<n-tooltip :placement="activeConfig.placement" trigger="hover">
|
||||
<template #trigger>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<a href="/" class="logo-height nowrap-hidden flex-center cursor-pointer">
|
||||
<system-logo class="w-32px h-32px" :color="primaryColor" />
|
||||
<h2 v-show="showTitle" class="pl-8px text-16px font-bold" :style="{ color: primaryColor }">{{ title }}</h2>
|
||||
<h2 v-show="showTitle" class="g_text-primary pl-8px text-16px font-bold">{{ title }}</h2>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
|
@ -23,3 +23,12 @@ export function shallowColor(color: string, alpha: number = 0.5) {
|
||||
export function darkenColor(color: string) {
|
||||
return chroma(color).darken(0.5).hex();
|
||||
}
|
||||
|
||||
/**
|
||||
* 给颜色加透明度
|
||||
* @param color - 颜色
|
||||
* @param alpha - 透明度
|
||||
*/
|
||||
export function addColorAlpha(color: string, alpha: number) {
|
||||
return chroma(color).alpha(alpha).hex();
|
||||
}
|
||||
|
@ -12,6 +12,6 @@ export {
|
||||
isMap
|
||||
} from './typeof';
|
||||
|
||||
export { brightenColor, shallowColor, darkenColor } from './color';
|
||||
export { brightenColor, shallowColor, darkenColor, addColorAlpha } from './color';
|
||||
|
||||
export { dynamicIconRender } from './icon';
|
||||
|
@ -24,6 +24,7 @@ export {
|
||||
brightenColor,
|
||||
shallowColor,
|
||||
darkenColor,
|
||||
addColorAlpha,
|
||||
dynamicIconRender
|
||||
} from './common';
|
||||
|
||||
|
@ -1,18 +1,46 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-spin class="flex-y-center flex-col" :show="loading">
|
||||
<n-gradient-text type="primary" size="32">工作台</n-gradient-text>
|
||||
<n-space>
|
||||
<n-button>Default</n-button>
|
||||
<n-button type="primary">Primary</n-button>
|
||||
<n-button type="info">Info</n-button>
|
||||
<n-button type="success">Success</n-button>
|
||||
<n-button type="warning">Warning</n-button>
|
||||
<n-button type="error">Error</n-button>
|
||||
</n-space>
|
||||
<n-space>
|
||||
<n-tag>Tag</n-tag>
|
||||
<n-tag type="primary">Primary Tag</n-tag>
|
||||
<n-spin :show="loading">
|
||||
<n-space :vertical="true">
|
||||
<div>
|
||||
<n-gradient-text type="primary" size="32">GradientText</n-gradient-text>
|
||||
<n-space>
|
||||
<n-gradient-text>Default</n-gradient-text>
|
||||
<n-gradient-text type="primary">Primary</n-gradient-text>
|
||||
<n-gradient-text type="info">Info</n-gradient-text>
|
||||
<n-gradient-text type="success">Success</n-gradient-text>
|
||||
<n-gradient-text type="warning">Warning</n-gradient-text>
|
||||
<n-gradient-text type="error">Error</n-gradient-text>
|
||||
</n-space>
|
||||
</div>
|
||||
<div>
|
||||
<n-gradient-text type="primary" size="32">Button</n-gradient-text>
|
||||
<n-space>
|
||||
<n-button>Default</n-button>
|
||||
<n-button type="primary">Primary</n-button>
|
||||
<n-button type="info">Info</n-button>
|
||||
<n-button type="success">Success</n-button>
|
||||
<n-button type="warning">Warning</n-button>
|
||||
<n-button type="error">Error</n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
<n-gradient-text type="primary" size="32">Tag</n-gradient-text>
|
||||
<n-space>
|
||||
<n-tag>Tag</n-tag>
|
||||
<n-tag type="primary">Primary</n-tag>
|
||||
<n-tag type="info">Info</n-tag>
|
||||
<n-tag type="success">Success</n-tag>
|
||||
<n-tag type="warning">Warning</n-tag>
|
||||
<n-tag type="error">Error</n-tag>
|
||||
</n-space>
|
||||
<div>
|
||||
<n-gradient-text type="primary" size="32">Switch | Checkbox | Radio</n-gradient-text>
|
||||
<n-space>
|
||||
<n-switch :default-value="true" />
|
||||
<n-checkbox :default-checked="true" />
|
||||
<n-radio :default-checked="true" />
|
||||
</n-space>
|
||||
</div>
|
||||
</n-space>
|
||||
</n-spin>
|
||||
</div>
|
||||
@ -20,7 +48,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { NGradientText, NSpace, NButton, NSpin, NTag } from 'naive-ui';
|
||||
import { NGradientText, NSpace, NButton, NSpin, NTag, NSwitch, NCheckbox, NRadio } from 'naive-ui';
|
||||
|
||||
const loading = ref(true);
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
<n-space :vertical="true" size="large">
|
||||
<div class="flex-y-center justify-between">
|
||||
<n-checkbox v-model:checked="rememberMe">记住我</n-checkbox>
|
||||
<span class="text-primary cursor-pointer" @click="toCurrentLogin('reset-pwd')">忘记密码?</span>
|
||||
<span class="g_text-primary cursor-pointer" @click="toCurrentLogin('reset-pwd')">忘记密码?</span>
|
||||
</div>
|
||||
<n-button type="primary" size="large" :block="true" :round="true" @click="handleSubmit">确定</n-button>
|
||||
<div class="flex-y-center justify-between">
|
||||
|
@ -9,7 +9,7 @@
|
||||
</header>
|
||||
<main class="pt-24px">
|
||||
<div v-for="item in modules" v-show="module === item.key" :key="item.key">
|
||||
<h3 class="text-18px text-primary font-medium">{{ item.label }}</h3>
|
||||
<h3 class="text-18px g_text-primary font-medium">{{ item.label }}</h3>
|
||||
<component :is="item.component" />
|
||||
</div>
|
||||
</main>
|
||||
|
Reference in New Issue
Block a user