diff --git a/mock/module/user.ts b/mock/module/user.ts index ac49f17..94344f8 100644 --- a/mock/module/user.ts +++ b/mock/module/user.ts @@ -60,7 +60,7 @@ const userRoutes = [ meta: { title: '多级菜单1', requiresAuth: true, - icon: 'icon-park-outline:alarm', + icon: 'icon-park-outline:list', }, }, { @@ -69,7 +69,7 @@ const userRoutes = [ meta: { title: '多级菜单2', requiresAuth: true, - icon: 'icon-park-outline:pic', + icon: 'icon-park-outline:list', }, children: [ { @@ -78,7 +78,7 @@ const userRoutes = [ meta: { title: '多级菜单2的详情页', requiresAuth: true, - icon: 'icon-park-outline:tool', + icon: 'icon-park-outline:list', hide: true, activeMenu: '/test/test2', }, @@ -91,7 +91,7 @@ const userRoutes = [ meta: { title: '多级菜单3', requiresAuth: true, - icon: 'icon-park-outline:tool', + icon: 'icon-park-outline:list', }, children: [ { @@ -100,7 +100,7 @@ const userRoutes = [ meta: { title: '多级菜单3-1', requiresAuth: true, - icon: 'icon-park-outline:tool', + icon: 'icon-park-outline:list', }, }, ], diff --git a/src/hook/index.ts b/src/hook/index.ts index 8a6054a..73ca960 100644 --- a/src/hook/index.ts +++ b/src/hook/index.ts @@ -1,3 +1,4 @@ export * from './useAppRouter'; export * from './useBoolean'; export * from './useLoading'; +export * from './useEcharts'; diff --git a/src/hook/useEcharts.ts b/src/hook/useEcharts.ts new file mode 100644 index 0000000..7a44a85 --- /dev/null +++ b/src/hook/useEcharts.ts @@ -0,0 +1,87 @@ +import * as echarts from 'echarts/core'; +import { nextTick, ref, onUnmounted, onMounted } from 'vue'; +import type { Ref } from 'vue'; + +import { BarChart, LineChart } from 'echarts/charts'; +// 系列类型的定义后缀都为 SeriesOption +import type { BarSeriesOption, LineSeriesOption } from 'echarts/charts'; + +import { + TitleComponent, + TooltipComponent, + GridComponent, + DatasetComponent, // 数据集组件 + TransformComponent, // 内置数据转换器组件 (filter, sort) +} from 'echarts/components'; +// 组件类型的定义后缀都为 ComponentOption +import type { + TitleComponentOption, + TooltipComponentOption, + GridComponentOption, + DatasetComponentOption, +} from 'echarts/components'; + +import { LabelLayout, UniversalTransition } from 'echarts/features'; +import { CanvasRenderer } from 'echarts/renderers'; + +// 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型 +export type ECOption = echarts.ComposeOption< + | BarSeriesOption + | LineSeriesOption + | TitleComponentOption + | TooltipComponentOption + | GridComponentOption + | DatasetComponentOption +>; + +// 注册必须的组件 +echarts.use([ + TitleComponent, + TooltipComponent, + GridComponent, + DatasetComponent, + TransformComponent, + BarChart, + LineChart, + LabelLayout, + UniversalTransition, + CanvasRenderer, +]); + +export function useEcharts(options: Ref<ECOption>) { + const domRef = ref<HTMLElement>(); + + let chart: echarts.ECharts | null = null; + + async function render() { + if (domRef.value) { + chart = echarts.init(domRef.value); + update(options.value); + } + } + function isRendered() { + return Boolean(domRef.value && chart); + } + function destroy() { + chart?.dispose(); + chart = null; + } + + function update(updateOptions: ECOption) { + if (isRendered()) { + chart!.setOption({ ...updateOptions, backgroundColor: 'transparent' }); + } + } + + onMounted(async () => { + await nextTick(); + render(); + }); + onUnmounted(() => { + destroy(); + }); + + return { + domRef, + }; +} diff --git a/src/views/plugin/charts/echarts/index.vue b/src/views/plugin/charts/echarts/index.vue index a9c5d58..1c8ccec 100644 --- a/src/views/plugin/charts/echarts/index.vue +++ b/src/views/plugin/charts/echarts/index.vue @@ -1,7 +1,38 @@ <template> - <div>echarts</div> + <n-space :vertical="true" :size="16"> + <n-card> + <div ref="pieRef" class="h-400px"></div> + </n-card> + <n-card> + <div ref="lineRef" class="h-400px"></div> + </n-card> + </n-space> </template> -<script setup lang="ts"></script> +<script setup lang="ts"> +import { ref } from 'vue'; +import type { Ref } from 'vue'; +import { type ECOption, useEcharts } from '@/hook'; + +const pieOptions = ref<ECOption>({ + title: { + text: 'ECharts 入门示例2', + }, + tooltip: {}, + xAxis: { + data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'], + }, + yAxis: {}, + series: [ + { + name: '销量', + type: 'bar', + data: [5, 20, 36, 10, 10, 20], + }, + ], +}) as Ref<ECOption>; +const { domRef: pieRef } = useEcharts(pieOptions); +const { domRef: lineRef } = useEcharts(pieOptions); +</script> <style scoped></style>