mirror of
https://gitee.com/dapppp/ruoyi-plus-vben5.git
synced 2026-03-15 05:42:01 +08:00
Merge branch 'main' of https://github.com/vbenjs/vue-vben-admin into antdv-next
This commit is contained in:
@@ -60,6 +60,11 @@ const sidebarTheme = computed(() => {
|
||||
return dark ? 'dark' : 'light';
|
||||
});
|
||||
|
||||
const sidebarThemeSub = computed(() => {
|
||||
const dark = isDark.value || preferences.theme.semiDarkSidebarSub;
|
||||
return dark ? 'dark' : 'light';
|
||||
});
|
||||
|
||||
const headerTheme = computed(() => {
|
||||
const dark = isDark.value || preferences.theme.semiDarkHeader;
|
||||
return dark ? 'dark' : 'light';
|
||||
@@ -240,6 +245,7 @@ const headerSlots = computed(() => {
|
||||
:sidebar-hidden="preferences.sidebar.hidden"
|
||||
:sidebar-mixed-width="preferences.sidebar.mixedWidth"
|
||||
:sidebar-theme="sidebarTheme"
|
||||
:sidebar-theme-sub="sidebarThemeSub"
|
||||
:sidebar-width="preferences.sidebar.width"
|
||||
:side-collapse-width="preferences.sidebar.collapseWidth"
|
||||
:tabbar-enable="preferences.tabbar.enable"
|
||||
@@ -355,7 +361,7 @@ const headerSlots = computed(() => {
|
||||
:collapse="preferences.sidebar.extraCollapse"
|
||||
:menus="wrapperMenus(extraMenus)"
|
||||
:rounded="isMenuRounded"
|
||||
:theme="sidebarTheme"
|
||||
:theme="sidebarThemeSub"
|
||||
/>
|
||||
</template>
|
||||
<template #side-extra-title>
|
||||
@@ -411,7 +417,7 @@ const headerSlots = computed(() => {
|
||||
|
||||
<template v-if="preferencesButtonPosition.fixed">
|
||||
<Preferences
|
||||
class="z-100 fixed bottom-20 right-0"
|
||||
class="z-100 fixed right-0 top-1/2 -translate-y-1/2 transform"
|
||||
@clear-preferences-and-logout="clearPreferencesAndLogout"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -6,7 +6,12 @@ import { useContentMaximize, useTabs } from '@vben/hooks';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import { useTabbarStore } from '@vben/stores';
|
||||
|
||||
import { TabsToolMore, TabsToolScreen, TabsView } from '@vben-core/tabs-ui';
|
||||
import {
|
||||
TabsToolMore,
|
||||
TabsToolRefresh,
|
||||
TabsToolScreen,
|
||||
TabsView,
|
||||
} from '@vben-core/tabs-ui';
|
||||
|
||||
import { useTabbar } from './use-tabbar';
|
||||
|
||||
@@ -19,7 +24,7 @@ defineProps<{ showIcon?: boolean; theme?: string }>();
|
||||
const route = useRoute();
|
||||
const tabbarStore = useTabbarStore();
|
||||
const { contentIsMaximize, toggleMaximize } = useContentMaximize();
|
||||
const { unpinTab } = useTabs();
|
||||
const { refreshTab, unpinTab } = useTabs();
|
||||
|
||||
const {
|
||||
createContextMenus,
|
||||
@@ -65,6 +70,10 @@ if (!preferences.tabbar.persist) {
|
||||
/>
|
||||
<div class="flex-center h-full">
|
||||
<TabsToolMore v-if="preferences.tabbar.showMore" :menus="menus" />
|
||||
<TabsToolRefresh
|
||||
v-if="preferences.tabbar.showRefresh"
|
||||
@refresh="refreshTab"
|
||||
/>
|
||||
<TabsToolScreen
|
||||
v-if="preferences.tabbar.showMaximize"
|
||||
:screen="contentIsMaximize"
|
||||
|
||||
@@ -58,7 +58,6 @@ function typeView(name: BuiltinThemeType) {
|
||||
case 'green': {
|
||||
return $t('preferences.theme.builtin.green');
|
||||
}
|
||||
|
||||
case 'neutral': {
|
||||
return $t('preferences.theme.builtin.neutral');
|
||||
}
|
||||
|
||||
@@ -2,8 +2,11 @@
|
||||
import type { ThemeModeType } from '@vben/types';
|
||||
import type { Component } from 'vue';
|
||||
|
||||
import { watch } from 'vue';
|
||||
|
||||
import { MoonStar, Sun, SunMoon } from '@vben/icons';
|
||||
import { $t } from '@vben/locales';
|
||||
import { usePreferences } from '@vben/preferences';
|
||||
|
||||
import SwitchItem from '../switch-item.vue';
|
||||
|
||||
@@ -13,8 +16,20 @@ defineOptions({
|
||||
|
||||
const modelValue = defineModel<string>({ default: 'auto' });
|
||||
const themeSemiDarkSidebar = defineModel<boolean>('themeSemiDarkSidebar');
|
||||
const themeSemiDarkSidebarSub = defineModel<boolean>('themeSemiDarkSidebarSub');
|
||||
const themeSemiDarkHeader = defineModel<boolean>('themeSemiDarkHeader');
|
||||
|
||||
const { layout } = usePreferences();
|
||||
|
||||
watch(
|
||||
() => themeSemiDarkSidebar.value,
|
||||
() => {
|
||||
if (!themeSemiDarkSidebar.value) {
|
||||
themeSemiDarkSidebarSub.value = themeSemiDarkSidebar.value;
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
const THEME_PRESET: Array<{ icon: Component; name: ThemeModeType }> = [
|
||||
{
|
||||
icon: Sun,
|
||||
@@ -70,11 +85,27 @@ function nameView(name: string) {
|
||||
|
||||
<SwitchItem
|
||||
v-model="themeSemiDarkSidebar"
|
||||
:disabled="modelValue === 'dark'"
|
||||
:disabled="
|
||||
modelValue === 'dark' ||
|
||||
layout === 'header-nav' ||
|
||||
layout === 'full-content'
|
||||
"
|
||||
:tip="$t('preferences.theme.darkSidebarTip')"
|
||||
class="mt-6"
|
||||
>
|
||||
{{ $t('preferences.theme.darkSidebar') }}
|
||||
</SwitchItem>
|
||||
<SwitchItem
|
||||
v-model="themeSemiDarkSidebarSub"
|
||||
:disabled="
|
||||
modelValue === 'dark' ||
|
||||
(layout !== 'header-mixed-nav' && layout !== 'sidebar-mixed-nav') ||
|
||||
!themeSemiDarkSidebar
|
||||
"
|
||||
:tip="$t('preferences.theme.darkSidebarSubTip')"
|
||||
>
|
||||
{{ $t('preferences.theme.darkSidebarSub') }}
|
||||
</SwitchItem>
|
||||
<SwitchItem v-model="themeSemiDarkHeader" :disabled="modelValue === 'dark'">
|
||||
{{ $t('preferences.theme.darkHeader') }}
|
||||
</SwitchItem>
|
||||
|
||||
@@ -90,6 +90,7 @@ const themeRadius = defineModel<string>('themeRadius');
|
||||
const themeButtonWaveMode = defineModel<string>('themeButtonWaveMode');
|
||||
const themeFontSize = defineModel<number>('themeFontSize');
|
||||
const themeSemiDarkSidebar = defineModel<boolean>('themeSemiDarkSidebar');
|
||||
const themeSemiDarkSidebarSub = defineModel<boolean>('themeSemiDarkSidebarSub');
|
||||
const themeSemiDarkHeader = defineModel<boolean>('themeSemiDarkHeader');
|
||||
|
||||
const sidebarEnable = defineModel<boolean>('sidebarEnable');
|
||||
@@ -321,6 +322,7 @@ async function handleReset() {
|
||||
v-model="themeMode"
|
||||
v-model:theme-semi-dark-header="themeSemiDarkHeader"
|
||||
v-model:theme-semi-dark-sidebar="themeSemiDarkSidebar"
|
||||
v-model:theme-semi-dark-sidebar-sub="themeSemiDarkSidebarSub"
|
||||
/>
|
||||
</Block>
|
||||
<Block :title="$t('preferences.theme.builtin.title')">
|
||||
|
||||
@@ -6,7 +6,17 @@ import type { Nullable } from '@vben/types';
|
||||
|
||||
import type EchartsUI from './echarts-ui.vue';
|
||||
|
||||
import { computed, nextTick, watch } from 'vue';
|
||||
import {
|
||||
computed,
|
||||
nextTick,
|
||||
onActivated,
|
||||
onBeforeUnmount,
|
||||
onDeactivated,
|
||||
onMounted,
|
||||
ref,
|
||||
unref,
|
||||
watch,
|
||||
} from 'vue';
|
||||
|
||||
import { usePreferences } from '@vben/preferences';
|
||||
|
||||
@@ -27,6 +37,8 @@ type EchartsThemeType = 'dark' | 'light' | null;
|
||||
function useEcharts(chartRef: Ref<EchartsUIType>) {
|
||||
let chartInstance: echarts.ECharts | null = null;
|
||||
let cacheOptions: EChartsOption = {};
|
||||
// echart是否处于激活状态
|
||||
const isActiveRef = ref(false);
|
||||
|
||||
const { isDark } = usePreferences();
|
||||
const { height, width } = useWindowSize();
|
||||
@@ -42,6 +54,11 @@ function useEcharts(chartRef: Ref<EchartsUIType>) {
|
||||
return maybeComponent.$el ?? null;
|
||||
};
|
||||
|
||||
onMounted(() => (isActiveRef.value = true));
|
||||
onActivated(() => (isActiveRef.value = true));
|
||||
onDeactivated(() => (isActiveRef.value = false));
|
||||
onBeforeUnmount(() => (isActiveRef.value = false));
|
||||
|
||||
const isElHidden = (el: HTMLElement | null): boolean => {
|
||||
if (!el) return true;
|
||||
return el.offsetHeight === 0 || el.offsetWidth === 0;
|
||||
@@ -71,6 +88,9 @@ function useEcharts(chartRef: Ref<EchartsUIType>) {
|
||||
options: EChartsOption,
|
||||
clear = true,
|
||||
): Promise<Nullable<echarts.ECharts>> => {
|
||||
if (!unref(isActiveRef)) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
cacheOptions = options;
|
||||
const currentOptions = {
|
||||
...options,
|
||||
@@ -105,7 +125,7 @@ function useEcharts(chartRef: Ref<EchartsUIType>) {
|
||||
});
|
||||
};
|
||||
|
||||
const updateDate = (
|
||||
const updateData = (
|
||||
option: EChartsOption,
|
||||
notMerge = false, // false = 合并(保留动画),true = 完全替换
|
||||
lazyUpdate = false, // true 时不立即重绘,适合短时间内多次调用
|
||||
@@ -156,8 +176,8 @@ function useEcharts(chartRef: Ref<EchartsUIType>) {
|
||||
|
||||
useResizeObserver(chartRef as never, resizeHandler);
|
||||
|
||||
watch(isDark, () => {
|
||||
if (chartInstance) {
|
||||
watch([isDark, isActiveRef], () => {
|
||||
if (chartInstance && unref(isActiveRef)) {
|
||||
chartInstance.dispose();
|
||||
initCharts();
|
||||
renderEcharts(cacheOptions);
|
||||
@@ -170,9 +190,10 @@ function useEcharts(chartRef: Ref<EchartsUIType>) {
|
||||
chartInstance?.dispose();
|
||||
});
|
||||
return {
|
||||
isActive: isActiveRef,
|
||||
renderEcharts,
|
||||
resize,
|
||||
updateDate,
|
||||
updateData,
|
||||
getChartInstance: () => chartInstance,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -384,9 +384,11 @@ onUnmounted(() => {
|
||||
<!-- 左侧操作区域或者title -->
|
||||
<template v-if="showToolbar" #toolbar-actions="slotProps">
|
||||
<slot v-if="showTableTitle" name="table-title">
|
||||
<div class="mr-1 pl-1 text-[1rem]">
|
||||
<div
|
||||
class="flex items-center justify-center gap-1 text-[1rem] font-bold"
|
||||
>
|
||||
{{ tableTitle }}
|
||||
<VbenHelpTooltip v-if="tableTitleHelp" trigger-class="pb-1">
|
||||
<VbenHelpTooltip v-if="tableTitleHelp">
|
||||
{{ tableTitleHelp }}
|
||||
</VbenHelpTooltip>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user