Ver código fonte

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

* 触发条件:echart所在页面开启keepalive 在其他页面切换颜色模式
ming4762 3 meses atrás
pai
commit
45b843f344

+ 24 - 3
packages/effects/plugins/src/echarts/use-echarts.ts

@@ -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,
@@ -154,8 +174,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);
@@ -168,6 +188,7 @@ function useEcharts(chartRef: Ref<EchartsUIType>) {
     chartInstance?.dispose();
   });
   return {
+    isActive: isActiveRef,
     renderEcharts,
     resize,
     updateData,

+ 1 - 0
playground/src/router/routes/modules/dashboard.ts

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