import type { EChartsOption } from 'echarts';
import type { Ref } from 'vue';
import type { Nullable } from '@vben/types';
import type EchartsUI from './echarts-ui.vue';
import { computed, nextTick, watch } from 'vue';
import { usePreferences } from '@vben/preferences';
import {
tryOnUnmounted,
useDebounceFn,
useResizeObserver,
useTimeoutFn,
useWindowSize,
} from '@vueuse/core';
import echarts from './echarts';
type EchartsUIType = typeof EchartsUI | undefined;
type EchartsThemeType = 'dark' | 'light' | null;
function useEcharts(chartRef: Ref<EchartsUIType>) {
let chartInstance: echarts.ECharts | null = null;
let cacheOptions: EChartsOption = {};
const { isDark } = usePreferences();
const { height, width } = useWindowSize();
const resizeHandler: () => void = useDebounceFn(resize, 200);
const getOptions = computed((): EChartsOption => {
if (!isDark.value) {
return {};
}
return {
backgroundColor: 'transparent',
};
});
const initCharts = (t?: EchartsThemeType) => {
const el = chartRef?.value?.$el;
if (!el) {
return;
}
chartInstance = echarts.init(el, t || isDark.value ? 'dark' : null);
return chartInstance;
};
const renderEcharts = (
options: EChartsOption,
clear = true,
): Promise<Nullable<echarts.ECharts>> => {
cacheOptions = options;
const currentOptions = {
...options,
...getOptions.value,
};
return new Promise((resolve) => {
if (chartRef.value?.offsetHeight === 0) {
useTimeoutFn(async () => {
resolve(await renderEcharts(currentOptions));
}, 30);
return;
}
nextTick(() => {
useTimeoutFn(() => {
if (!chartInstance) {
const instance = initCharts();
if (!instance) return;
}
clear && chartInstance?.clear();
chartInstance?.setOption(currentOptions);
resolve(chartInstance);
}, 30);
});
});
};
function resize() {
chartInstance?.resize({
animation: {
duration: 300,
easing: 'quadraticIn',
},
});
}
watch([width, height], () => {
resizeHandler?.();
});
useResizeObserver(chartRef as never, resizeHandler);
watch(isDark, () => {
if (chartInstance) {
chartInstance.dispose();
initCharts();
renderEcharts(cacheOptions);
resize();
}
});
tryOnUnmounted(() => {
// 销毁实例,释放资源
chartInstance?.dispose();
});
return {
renderEcharts,
resize,
getChartInstance: () => chartInstance,
};
}
export { useEcharts };
export type { EchartsUIType };
这段 TypeScript 代码定义了一个名为 useEcharts
的自定义钩子函数,用于在 Vue 项目中集成和管理 ECharts 图表。下面是对代码详细的解释:
import type { EChartsOption } from 'echarts'; // 导入 ECharts 选项类型
import type { Ref } from 'vue'; // 导入 Vue 的 Ref 类型
import type { Nullable } from '@vben/types'; // 导入可空类型
import type EchartsUI from './echarts-ui.vue'; // 导入 EchartsUI 组件类型
import { computed, nextTick, watch } from 'vue'; // 导入 Vue 的计算属性、下一个 DOM 更新周期方法和监听器
import { usePreferences } from '@vben/preferences'; // 导入偏好设置钩子
import {
tryOnUnmounted,
useDebounceFn,
useResizeObserver,
useTimeoutFn,
useWindowSize,
} from '@vueuse/core'; // 导入 VueUse 核心库的一些钩子
import echarts from './echarts'; // 导入 ECharts 库
Ref
类型、可空类型以及 EchartsUI
组件类型。vue
中导入了 computed
、nextTick
和 watch
等功能,从 @vben/preferences
中导入了偏好设置钩子,从 @vueuse/core
中导入了一些实用的钩子,最后导入了 ECharts 库。type EchartsUIType = typeof EchartsUI | undefined; // 定义 EchartsUI 组件类型
type EchartsThemeType = 'dark' | 'light' | null; // 定义 ECharts 主题类型
EchartsUIType
:表示 EchartsUI
组件类型,可能为 undefined
。EchartsThemeType
:表示 ECharts 的主题类型,有 'dark'
、'light'
或 null
三种可能。useEcharts
函数function useEcharts(chartRef: Ref<EchartsUIType>) {
let chartInstance: echarts.ECharts | null = null; // 初始化 ECharts 实例
let cacheOptions: EChartsOption = {}; // 初始化缓存的 ECharts 选项
const { isDark } = usePreferences(); // 获取是否为深色模式
const { height, width } = useWindowSize(); // 获取窗口的高度和宽度
const resizeHandler: () => void = useDebounceFn(resize, 200); // 创建防抖的 resize 处理函数
const getOptions = computed((): EChartsOption => {
if (!isDark.value) {
return {};
}
return {
backgroundColor: 'transparent',
};
}); // 计算根据深色模式的 ECharts 选项
chartInstance
:用于存储 ECharts 实例,初始值为 null
。cacheOptions
:用于缓存 ECharts 选项,初始值为空对象。isDark
:通过 usePreferences
钩子获取当前是否为深色模式。height
和 width
:通过 useWindowSize
钩子获取窗口的高度和宽度。useDebounceFn
创建一个防抖的 resize
处理函数,防抖时间为 200 毫秒。getOptions
是一个计算属性,根据 isDark
的值返回不同的 ECharts 选项。如果是深色模式,返回一个包含透明背景色的选项;否则返回空对象。 const initCharts = (t?: EchartsThemeType) => {
const el = chartRef?.value?.$el;
if (!el) {
return;
}
chartInstance = echarts.init(el, t || isDark.value ? 'dark' : null);
return chartInstance;
}; // 初始化 ECharts 实例
initCharts
函数用于初始化 ECharts 实例。它首先获取 chartRef
对应的 DOM 元素,如果元素不存在则直接返回。然后使用 echarts.init
方法初始化 ECharts 实例,并根据传入的主题或当前的深色模式设置主题。最后返回初始化后的实例。 const renderEcharts = (
options: EChartsOption,
clear = true,
): Promise<Nullable<echarts.ECharts>> => {
cacheOptions = options;
const currentOptions = {
...options,
...getOptions.value,
};
return new Promise((resolve) => {
if (chartRef.value?.offsetHeight === 0) {
useTimeoutFn(async () => {
resolve(await renderEcharts(currentOptions));
}, 30);
return;
}
nextTick(() => {
useTimeoutFn(() => {
if (!chartInstance) {
const instance = initCharts();
if (!instance) return;
}
clear && chartInstance?.clear();
chartInstance?.setOption(currentOptions);
resolve(chartInstance);
}, 30);
});
});
}; // 渲染 ECharts 图表
renderEcharts
函数用于渲染 ECharts 图表。它接收两个参数:options
表示要渲染的 ECharts 选项,clear
表示是否清除之前的图表内容,默认为 true
。options
缓存到 cacheOptions
中,然后合并 options
和 getOptions
的值得到 currentOptions
。chartRef
的高度为 0,说明图表容器还未完全渲染,使用 useTimeoutFn
延迟 30 毫秒后再次调用 renderEcharts
函数。nextTick
中使用 useTimeoutFn
延迟 30 毫秒后进行图表的渲染。如果 chartInstance
不存在,则调用 initCharts
函数初始化实例。然后根据 clear
的值决定是否清除之前的图表内容,并使用 setOption
方法设置新的选项。最后通过 resolve
返回 chartInstance
。 function resize() {
chartInstance?.resize({
animation: {
duration: 300,
easing: 'quadraticIn',
},
});
} // 调整 ECharts 图表大小
resize
函数用于调整 ECharts 图表的大小。它调用 chartInstance
的 resize
方法,并设置了一个动画效果,动画持续时间为 300 毫秒,缓动函数为 'quadraticIn'
。 watch([width, height], () => {
resizeHandler?.();
}); // 监听窗口大小变化,调用 resize 处理函数
useResizeObserver(chartRef as never, resizeHandler); // 监听图表容器大小变化,调用 resize 处理函数
watch(isDark, () => {
if (chartInstance) {
chartInstance.dispose();
initCharts();
renderEcharts(cacheOptions);
resize();
}
}); // 监听深色模式变化,重新初始化和渲染图表
watch
监听 width
和 height
的变化,当窗口大小改变时,调用防抖的 resizeHandler
函数。useResizeObserver
监听 chartRef
对应的 DOM 元素的大小变化,当容器大小改变时,调用 resizeHandler
函数。watch
监听 isDark
的变化,当深色模式改变时,销毁当前的 chartInstance
,重新初始化 ECharts 实例,渲染缓存的选项,并调整图表大小。 tryOnUnmounted(() => {
// 销毁实例,释放资源
chartInstance?.dispose();
}); // 在组件卸载时销毁 ECharts 实例
tryOnUnmounted
钩子,在组件卸载时销毁 chartInstance
,释放资源。 return {
renderEcharts,
resize,
getChartInstance: () => chartInstance,
};
}
export { useEcharts }; // 导出 useEcharts 钩子
export type { EchartsUIType }; // 导出 EchartsUIType 类型
useEcharts
函数返回一个对象,包含 renderEcharts
、resize
和 getChartInstance
三个方法。useEcharts
钩子和 EchartsUIType
类型,供其他组件使用。 综上所述,这段代码通过自定义钩子 useEcharts
封装了 ECharts 的初始化、渲染、大小调整和主题切换等功能,方便在 Vue 项目中使用 ECharts 图表。同时,通过监听窗口和容器大小变化以及深色模式的改变,实现了图表的自适应和动态更新。
此代码定义了一个名为 useEcharts
的自定义钩子,这个钩子就像是一个神奇的小助手♂️,专门用于在 Vue 项目中管理 ECharts 图表的各种操作:
这个代码适用于需要在 Vue 组件中集成 ECharts 图表,并且有以下需求的场景:
代码中导入了各种模块,这些模块就像是不同的工具,共同协作完成代码的功能:
定义了 EchartsUIType
和 EchartsThemeType
类型,它们的作用和用途如下:
EchartsUIType
:就像是一个分类标签️,用于对 ECharts 图表的 UI 样式进行分类和定义,让代码能够更清晰地管理和使用不同的 UI 样式。EchartsThemeType
:类似于一个主题模板,用于定义 ECharts 图表的主题,比如浅色主题、深色主题等,方便在不同的主题之间进行切换。useEcharts
函数的整体结构和主要逻辑流程就像是一场精心策划的演出:
导出的 useEcharts
钩子和 EchartsUIType
类型有着重要的作用:
useEcharts
钩子:就像是一个可以复用的工具包️,其他 Vue 组件可以通过导入这个钩子,轻松地在自己的组件中集成 ECharts 图表,并使用其提供的各种功能。EchartsUIType
类型:为其他代码提供了一个统一的 UI 样式分类标准,方便不同的组件在使用 ECharts 图表时,能够遵循相同的 UI 规范,保持整体的一致性。EChartsOption
类型导入EChartsOption
类型就像是一份严格的“设计蓝图”,它是 ECharts 配置选项的类型定义。在我们使用 ECharts 绘制图表时,需要传入一个配置对象来告诉 ECharts 我们想要绘制什么样的图表,比如图表的类型(柱状图、折线图等)、数据内容、样式设置等。而 EChartsOption
类型的存在,就是为了规范这个传入的配置对象。
它可以帮助我们在编写代码时,提前发现配置对象中可能存在的错误,比如属性名拼写错误、属性类型不匹配等。就好比在建造房子之前,先有一份详细准确的蓝图,这样在施工过程中就能避免很多不必要的错误和麻烦。
例如,在 TypeScript 中使用 ECharts 时,如果我们定义一个配置对象并指定其类型为 EChartsOption
:
import { EChartsOption } from 'echarts';
const option: EChartsOption = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [{
data: [820, 932, 901, 934, 1290, 1330, 1320],
type: 'line'
}]
};
这样,当我们写错属性名或者属性类型不匹配时,编译器就会及时给我们报错提示。
echarts
库导入导入 echarts
库就像是打开了一个功能强大的“工具箱”,我们可以使用这个工具箱里的各种工具来完成 ECharts 的初始化、渲染等功能。
ECharts 库提供了一系列的方法和属性,让我们能够方便地创建和操作图表。比如,我们可以使用 echarts.init
方法来初始化一个 ECharts 实例,然后使用 setOption
方法将配置对象应用到这个实例上,从而实现图表的渲染。
示例代码如下:
import * as echarts from 'echarts';
// 初始化 ECharts 实例
const myChart = echarts.init(document.getElementById('main'));
// 设置配置项并渲染图表
const option = {
// 配置项内容
};
myChart.setOption(option);
通过导入 echarts
库,我们就可以利用这些功能轻松地在网页上绘制出各种精美的图表。
Ref
类型导入在 Vue 中,Ref
类型就像是一个“魔法盒子”,用于创建响应式引用。它可以让我们在代码中方便地引用某个值,并且当这个值发生变化时,与之关联的 DOM 元素或者其他依赖项会自动更新。
在我们的代码中,Ref
类型主要用于引用 EchartsUI 组件。通过 Ref
,我们可以获取到 EchartsUI 组件的实例,进而对其进行操作。
例如:
这样,我们就可以通过 echartsRef.value
来访问 EchartsUI 组件的实例,调用其方法或者获取其属性。
computed
、nextTick
和 watch
导入computed
的作用computed
就像是一个“智能计算器”,用于创建计算属性。计算属性是根据其他数据动态计算得出的属性,它会根据依赖的数据自动更新。
当我们有一些数据需要根据其他数据进行计算时,使用计算属性可以让代码更加简洁和易于维护。例如:
原始数据: {{ num }}
计算结果: {{ doubleNum }}
在这个例子中,doubleNum
就是一个计算属性,它的值会根据 num
的变化而自动更新。
nextTick
的作用nextTick
就像是一个“时间旅行者”️♂️,用于在 DOM 更新后执行回调。在 Vue 中,数据的更新是异步的,当我们修改数据后,DOM 不会立即更新。而 nextTick
可以让我们在 DOM 更新完成后再执行一些操作。
例如,当我们需要获取更新后的 DOM 元素的尺寸或者位置时,就可以使用 nextTick
:
{{ message }}
这样,我们就可以确保在 DOM 更新完成后再执行相应的操作。
watch
的作用watch
就像是一个“监控摄像头”,用于监听数据变化并执行相应操作。当我们需要在某个数据发生变化时执行一些特定的逻辑时,就可以使用 watch
。
例如:
在这个例子中,当 inputValue
的值发生变化时,watch
会自动触发回调函数,我们可以在回调函数中执行相应的操作。
usePreferences
导入usePreferences
钩子就像是一个“个人秘书”,用于获取用户的偏好设置。在我们的代码中,主要用于判断用户是否选择了深色模式。
用户的偏好设置可能包括主题模式、字体大小、语言等,通过 usePreferences
钩子,我们可以方便地获取这些设置,并根据用户的偏好来调整页面的显示效果。
例如:
这样,我们就可以根据 isDarkMode
的值来动态添加或移除 dark-mode
类,从而实现深色模式的切换。
EchartsUI
组件导入导入 EchartsUI
组件就像是为图表找到了一个“家”,其目的是为了获取图表容器的 DOM 元素。
EchartsUI 组件通常是一个包含图表容器的组件,我们通过导入这个组件并在页面中使用它,就可以获取到这个容器的 DOM 元素,然后在这个容器中初始化和渲染 ECharts 图表。
例如:
这样,我们就可以通过 chartContainer.value
来获取图表容器的 DOM 元素,进而在这个元素上初始化 ECharts 实例。
tryOnUnmounted
导入tryOnUnmounted
就像是一个“清洁工”,用于在组件卸载时执行清理操作。在我们的代码中,主要用于销毁 ECharts 实例。
当一个组件被卸载时,如果不及时清理一些资源,可能会导致内存泄漏等问题。而 tryOnUnmounted
可以确保在组件卸载时,我们能够执行一些必要的清理操作,比如销毁 ECharts 实例。
例如:
这样,当组件被卸载时,就会自动执行销毁 ECharts 实例的操作,避免资源的浪费。
useDebounceFn
导入useDebounceFn
就像是一个“节流阀”,通过防抖处理减少 resize
函数的调用频率,提高性能。
当我们监听元素的大小变化时,比如窗口大小变化或者图表容器大小变化,resize
事件可能会频繁触发。如果每次触发都执行 resize
函数,会导致性能问题。而 useDebounceFn
可以让 resize
函数在一段时间内只执行一次,避免不必要的性能开销。
例如:
在这个例子中,useDebounceFn
会让 handleResize
函数在 300 毫秒内只执行一次,从而减少了函数的调用频率,提高了性能。
useResizeObserver
导入useResizeObserver
就像是一个“尺寸侦探”️,用于监听元素大小变化。在我们的代码中,主要用于监听图表容器的大小变化并调用 resize
函数。
当图表容器的大小发生变化时,我们需要及时调整图表的大小,以保证图表能够正确显示。useResizeObserver
可以帮助我们实时监测图表容器的大小变化,一旦发生变化,就会触发相应的回调函数,我们可以在回调函数中调用 resize
函数来调整图表的大小。
例如:
这样,当图表容器的大小发生变化时,就会自动调用 resize
函数来调整图表的大小,保证图表的显示效果。
useTimeoutFn
导入useTimeoutFn
就像是一个“定时闹钟”⏰,用于在指定时间后执行回调函数。在代码中用于处理图表渲染时的延迟操作。
有时候,我们需要在图表渲染之前或者之后执行一些延迟操作,比如等待数据加载完成后再渲染图表,或者在图表渲染完成后执行一些动画效果。useTimeoutFn
可以帮助我们实现这些延迟操作。
例如:
这样,就可以在 1000 毫秒后执行图表渲染的逻辑,实现延迟操作。
useWindowSize
导入useWindowSize
就像是一个“窗口测量员”,用于获取窗口的高度和宽度,以便在窗口大小变化时调整图表大小。
当窗口大小发生变化时,图表的大小也需要相应地调整,以保证图表能够适应不同的窗口尺寸。useWindowSize
可以实时获取窗口的高度和宽度,我们可以根据这些信息来动态调整图表的大小。
例如:
这样,当窗口大小发生变化时,就可以根据新的窗口高度和宽度来调整图表的大小,保证图表的显示效果。
EchartsUIType
类型EchartsUIType
被定义为 typeof EchartsUI | undefined
,这到底是什么意思呢?
typeof EchartsUI
:这里的 typeof
是一个操作符,它会返回 EchartsUI
的类型。也就是说,它代表的是 EchartsUI
这个组件本身所具有的类型。想象一下,EchartsUI
就像是一个独特的“物品”,而 typeof EchartsUI
就是描述这个“物品”特征的标签️。| undefined
:这个 |
符号在类型定义里表示“或”的关系。undefined
是 JavaScript 中的一个原始值,表示变量已声明但未赋值,或者函数没有返回值。所以 | undefined
意味着 EchartsUIType
除了可以是 EchartsUI
的类型,还可以是未定义的情况。就好比一个盒子,里面要么装着 EchartsUI
这个“物品”,要么就是空的(未定义)。综上所述,EchartsUIType
表示的就是 EchartsUI
组件的类型或者未定义的情况。
这个类型在代码中主要用于 chartRef
的类型定义,这是为什么呢?
在 React 等框架中,ref
是一种用来引用 DOM 节点或者组件实例的方式。chartRef
就是用来引用 EchartsUI
组件的一个引用对象。通过将 chartRef
的类型定义为 EchartsUIType
,可以确保我们引用的是 EchartsUI
组件。
举个例子,如果我们不小心把 chartRef
引用到了其他类型的组件或者变量上,由于类型不匹配,编译器就会发出警告⚠️,这样就能避免一些潜在的错误。就好像我们给一个特定的“停车位”(chartRef
)设置了只能停放“EchartsUI
汽车”的规则,一旦有其他“车辆”试图停进去,就会被阻止。
EchartsThemeType
类型EchartsThemeType
被定义为 'dark' | 'light' | null
,下面来详细解释一下。
'dark'
和 'light'
:ECharts 是一个强大的可视化库,它支持不同的主题,其中 'dark'
代表深色主题,'light'
代表浅色主题。这就好比我们可以给一幅画选择不同的背景颜色,深色背景会让画面显得神秘、沉稳,浅色背景则会让画面更加明亮、清新。null
:在 JavaScript 中,null
表示一个空对象指针。在这里,null
表示不指定任何主题。就好像我们选择不给画设置背景颜色,让它保持默认的样子️。所以,EchartsThemeType
表示的就是 ECharts 支持的主题类型。
这个类型在代码中的主要使用场景是在 initCharts
函数中指定 ECharts 实例的主题。
initCharts
函数的作用是初始化一个 ECharts 实例,在初始化的过程中,我们可以通过传入 EchartsThemeType
类型的参数来指定使用的主题。例如:
function initCharts(theme: EchartsThemeType) {
// 初始化 ECharts 实例
const myChart = echarts.init(dom, theme);
// 其他初始化操作
// ...
}
通过这种方式,我们可以根据不同的需求灵活地选择 ECharts 实例的主题。如果我们想要一个深色主题的图表,就可以调用 initCharts('dark')
;如果想要浅色主题,就调用 initCharts('light')
;如果不想指定主题,就调用 initCharts(null)
。这样可以让我们的图表在不同的场景下都能呈现出最佳的视觉效果。
useEcharts
钩子函数详解chartInstance
变量chartInstance
变量在 useEcharts
钩子函数中扮演着至关重要的角色。它的主要作用是存储 ECharts 实例。想象一下,ECharts 实例就像是一个功能强大的“魔法盒子”,里面包含了图表的各种属性和方法。通过将这个“魔法盒子”存储在 chartInstance
变量中,我们就可以在后续的代码里轻松地对图表进行各种操作,比如渲染图表,让它在页面上显示出来;或者调整图表的大小,使它能够完美适配不同的屏幕尺寸。
cacheOptions
变量cacheOptions
变量就像是一个“仓库”,它的用途是缓存传入的 ECharts 配置选项。在实际开发中,我们可能会根据不同的条件或者用户的操作来重新渲染图表。这时候,就可以从 cacheOptions
这个“仓库”里取出之前存储的配置选项,然后用这些选项来重新渲染图表,避免了重复传递配置选项的麻烦,提高了代码的效率和可维护性。
isDark
获取通过 usePreferences
钩子来获取 isDark
变量,这就像是给我们的代码装上了一个“模式探测器”️。isDark
变量用于判断当前是否处于深色模式。在不同的模式下,图表的显示效果可能会有所不同,比如在深色模式下,我们可能需要调整图表的背景颜色、字体颜色等配置,让图表在深色背景下也能清晰地显示出来。所以,获取 isDark
变量可以帮助我们根据当前的模式动态地调整图表的配置。
width
和 height
获取使用 useWindowSize
钩子来获取窗口的宽度和高度,就像是给我们的图表安装了一个“尺寸追踪器”。在现代的网页设计中,页面需要能够自适应不同的屏幕尺寸。当用户调整浏览器窗口的大小时,图表也需要相应地调整大小,以保证良好的用户体验。通过获取窗口的宽度和高度,我们可以监听窗口大小的变化,并在变化发生时调用相应的函数来调整图表的大小,让图表始终与窗口大小保持一致。
resizeHandler
函数resizeHandler
函数是通过 useDebounceFn
对 resize
函数进行防抖处理后的函数。想象一下,当用户频繁地调整窗口大小时,如果每次窗口大小发生微小的变化都立即调用 resize
函数来调整图表大小,那么会导致 resize
函数被频繁调用,这不仅会消耗大量的性能,还可能会让图表的调整效果变得不流畅。而 resizeHandler
函数就像是一个“缓冲器”,它会在用户停止调整窗口大小一段时间后才调用 resize
函数,减少了 resize
函数的调用频率,提高了性能,让图表的调整更加平滑。
getOptions
getOptions
计算属性的计算逻辑就像是一个“智能转换器”。它会根据 isDark
的值来返回不同的 ECharts 配置选项。当 isDark
为 true
,也就是处于深色模式时,它会将图表的背景颜色设置为透明,这样可以让图表更好地融入深色背景中。而当 isDark
为 false
时,它会返回默认的配置选项。
这个计算属性在代码中的使用场景就像是一个“拼图块”。它主要用于合并到最终的 ECharts 配置选项中。在渲染图表时,我们需要将各种配置选项组合在一起,而 getOptions
计算属性提供了根据不同模式动态生成的配置选项,将它合并到最终的配置中,就可以让图表根据当前的模式进行正确的渲染。
initCharts
函数initCharts
函数的主要功能是初始化 ECharts 实例,就像是给图表“搭建一个家”。它会根据传入的主题类型或者当前的深色模式来设置图表的主题。不同的主题可以让图表呈现出不同的风格,比如明亮的风格或者深色的风格,以满足不同用户的需求。
在函数内部,首先需要获取图表容器的 DOM 元素,这就像是找到图表“家”的具体位置。通常会使用 document.getElementById
或者 ref
等方式来获取 DOM 元素。然后,调用 echarts.init
方法,传入图表容器的 DOM 元素和主题类型,就可以初始化一个 ECharts 实例,将这个实例存储在 chartInstance
变量中,方便后续的操作。
renderEcharts
函数renderEcharts
函数的主要功能是渲染 ECharts 图表,就像是给图表“穿上漂亮的衣服”。它会处理一些特殊情况,比如图表容器高度为 0 的情况,这时候可能需要等待容器高度正常后再进行渲染。同时,它会在 DOM 更新后进行渲染操作,确保图表能够正确地显示在页面上。
在函数内部,首先会合并配置选项,将 cacheOptions
和 getOptions
等配置选项组合在一起,形成最终的配置。然后,会处理延迟渲染的情况,比如使用 nextTick
等方法确保在 DOM 更新后再进行渲染。接着,会清除之前的图表,避免出现重叠或者显示异常的问题。最后,调用 chartInstance.setOption
方法,将最终的配置选项设置到 ECharts 实例中,完成图表的渲染。
函数返回的 Promise
对象就像是一个“承诺使者”。它在图表渲染完成后返回 ECharts 实例。我们可以通过 then
方法来处理这个返回的实例,比如在图表渲染完成后进行一些额外的操作,如添加事件监听器等。
resize
函数resize
函数的作用是调整 ECharts 实例的大小,就像是给图表“量身定制衣服”。它还设置了动画效果,让图表在调整大小时能够平滑地过渡,给用户带来更好的视觉体验。
在函数内部,会调用 chartInstance.resize
方法,传入一些配置参数,如动画效果的配置等,来实现图表大小的调整。通过这个方法,ECharts 实例会根据新的大小重新计算和绘制图表,让图表适应新的尺寸。
watch([width, height], () => { resizeHandler?.(); })
就像是一个“窗口变化哨兵”。当窗口的宽度或者高度发生变化时,它会触发回调函数,调用 resizeHandler
函数进行图表大小的调整。这样,无论用户如何调整窗口大小,图表都能及时地做出响应,保持良好的显示效果。
useResizeObserver(chartRef as never, resizeHandler)
就像是一个“容器变化侦探”️♂️。它会监听图表容器的大小变化,当容器的大小发生改变时,会调用 resizeHandler
函数进行图表大小的调整。这对于一些动态改变容器大小的场景非常有用,比如在页面布局发生变化时,图表能够自动调整大小。
watch(isDark, () => { ... })
就像是一个“模式变化警报器”。当深色模式发生变化时,它会触发回调函数。在回调函数中,会销毁当前的 ECharts 实例,就像是拆除旧的“房子”,然后重新初始化并渲染图表,给图表换上适应新模式的“衣服”,让图表在不同的模式下都能正常显示。
tryOnUnmounted
函数tryOnUnmounted
函数的作用是在组件卸载时销毁 ECharts 实例,就像是在离开“房子”时关闭所有的电器设备,释放资源⚡。如果不销毁 ECharts 实例,它会一直占用内存,可能会导致内存泄漏,影响页面的性能。通过在组件卸载时销毁实例,可以避免这种问题,让页面更加稳定和高效。
返回对象中包含了 renderEcharts
、resize
和 getChartInstance
方法。
renderEcharts
方法就像是一个“渲染大师”,用于渲染图表,将配置选项应用到图表上,让图表显示在页面上。resize
方法就像是一个“尺寸调整师”,用于调整图表的大小,让图表适应不同的屏幕尺寸。getChartInstance
方法就像是一个“实例获取员”,用于获取 ECharts 实例,方便在其他地方对图表进行进一步的操作。通过返回这些方法,外部组件可以方便地使用 useEcharts
钩子提供的功能,实现图表的渲染、调整等操作。useEcharts
钩子导出在开发 Vue 项目时,我们经常会使用 ECharts 库来创建各种精美的图表。为了更方便地在不同的 Vue 组件中管理和使用 ECharts 图表,我们将 useEcharts
钩子导出。这个钩子封装了与 ECharts 相关的一些通用逻辑,比如图表的初始化、数据更新、事件绑定等。通过导出这个钩子,其他 Vue 组件可以直接引入并使用它,避免了在每个组件中重复编写相同的 ECharts 管理代码,提高了代码的复用性和可维护性。
以下是在其他组件中使用 useEcharts
钩子的详细步骤:
useEcharts
钩子的 Vue 组件中,首先要引入它。假设 useEcharts
钩子定义在 hooks/useEcharts.js
文件中,引入代码如下:import { useEcharts } from '@/hooks/useEcharts';
setup
函数中调用 useEcharts
钩子,并根据需要进行配置。示例代码如下:
在上述代码中,我们首先创建了一个 chartRef
用于引用图表的容器元素。然后调用 useEcharts
钩子,并传入 chartRef
。最后,调用 initChart
方法并传入 ECharts 的配置项来初始化图表。
EchartsUIType
类型导出在 TypeScript 项目中,类型定义非常重要,它可以帮助我们在开发过程中更早地发现类型错误,提高代码的健壮性。EchartsUIType
类型是对 ECharts 相关 UI 元素的类型定义,比如图表的配置项、样式等。通过导出 EchartsUIType
类型,其他模块可以直接引用这个类型,确保在使用 ECharts 相关数据时类型的一致性和准确性。
以下是在其他模块中使用 EchartsUIType
类型的详细步骤:
EchartsUIType
类型的模块中,首先要引入它。假设 EchartsUIType
类型定义在 types/EchartsUIType.ts
文件中,引入代码如下:import { EchartsUIType } from '@/types/EchartsUIType';
EchartsUIType
类型进行类型注解。示例代码如下:import { EchartsUIType } from '@/types/EchartsUIType';
function updateChartConfig(config: EchartsUIType): void {
// 在这里可以对图表配置进行更新操作
console.log('Updating chart config:', config);
}
const chartConfig: EchartsUIType = {
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [120, 200, 150, 80, 70, 110, 130],
type: 'bar'
}
]
};
updateChartConfig(chartConfig);
在上述代码中,我们定义了一个 updateChartConfig
函数,它接受一个 EchartsUIType
类型的参数。然后创建了一个 chartConfig
对象,并将其类型注解为 EchartsUIType
。最后调用 updateChartConfig
函数并传入 chartConfig
,这样可以确保传入的参数类型符合要求。