fix: fix bug where renderEcharts gets stuck in a dead loop (#7561)

* 触发条件:echart所在页面开启keepalive 在其他页面切换颜色模式
This commit is contained in:
ming4762
2026-02-26 06:21:08 +08:00
committed by GitHub
parent 191fd90f06
commit 45b843f344
2 changed files with 25 additions and 3 deletions

View File

@@ -6,7 +6,17 @@ import type { Nullable } from '@vben/types';
import type EchartsUI from './echarts-ui.vue'; 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'; import { usePreferences } from '@vben/preferences';
@@ -27,6 +37,8 @@ type EchartsThemeType = 'dark' | 'light' | null;
function useEcharts(chartRef: Ref<EchartsUIType>) { function useEcharts(chartRef: Ref<EchartsUIType>) {
let chartInstance: echarts.ECharts | null = null; let chartInstance: echarts.ECharts | null = null;
let cacheOptions: EChartsOption = {}; let cacheOptions: EChartsOption = {};
// echart是否处于激活状态
const isActiveRef = ref(false);
const { isDark } = usePreferences(); const { isDark } = usePreferences();
const { height, width } = useWindowSize(); const { height, width } = useWindowSize();
@@ -42,6 +54,11 @@ function useEcharts(chartRef: Ref<EchartsUIType>) {
return maybeComponent.$el ?? null; 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 => { const isElHidden = (el: HTMLElement | null): boolean => {
if (!el) return true; if (!el) return true;
return el.offsetHeight === 0 || el.offsetWidth === 0; return el.offsetHeight === 0 || el.offsetWidth === 0;
@@ -71,6 +88,9 @@ function useEcharts(chartRef: Ref<EchartsUIType>) {
options: EChartsOption, options: EChartsOption,
clear = true, clear = true,
): Promise<Nullable<echarts.ECharts>> => { ): Promise<Nullable<echarts.ECharts>> => {
if (!unref(isActiveRef)) {
return Promise.resolve(null);
}
cacheOptions = options; cacheOptions = options;
const currentOptions = { const currentOptions = {
...options, ...options,
@@ -154,8 +174,8 @@ function useEcharts(chartRef: Ref<EchartsUIType>) {
useResizeObserver(chartRef as never, resizeHandler); useResizeObserver(chartRef as never, resizeHandler);
watch(isDark, () => { watch([isDark, isActiveRef], () => {
if (chartInstance) { if (chartInstance && unref(isActiveRef)) {
chartInstance.dispose(); chartInstance.dispose();
initCharts(); initCharts();
renderEcharts(cacheOptions); renderEcharts(cacheOptions);
@@ -168,6 +188,7 @@ function useEcharts(chartRef: Ref<EchartsUIType>) {
chartInstance?.dispose(); chartInstance?.dispose();
}); });
return { return {
isActive: isActiveRef,
renderEcharts, renderEcharts,
resize, resize,
updateData, updateData,

View File

@@ -20,6 +20,7 @@ const routes: RouteRecordRaw[] = [
affixTab: true, affixTab: true,
icon: 'lucide:area-chart', icon: 'lucide:area-chart',
title: $t('page.dashboard.analytics'), title: $t('page.dashboard.analytics'),
keepAlive: true,
}, },
}, },
{ {