refactor(projects): 代码优化
ISSUES CLOSED: \
This commit is contained in:
parent
6a5a357f50
commit
d9ac7e4de0
@ -1,4 +1,4 @@
|
|||||||
import { ref, watch, nextTick, onUnmounted, computed } from 'vue';
|
import { ref, watch, nextTick, onUnmounted } from 'vue';
|
||||||
import type { Ref, ComputedRef } from 'vue';
|
import type { Ref, ComputedRef } from 'vue';
|
||||||
import * as echarts from 'echarts/core';
|
import * as echarts from 'echarts/core';
|
||||||
import { BarChart, LineChart, PieChart, ScatterChart } from 'echarts/charts';
|
import { BarChart, LineChart, PieChart, ScatterChart } from 'echarts/charts';
|
||||||
@ -23,6 +23,7 @@ import type {
|
|||||||
import { LabelLayout, UniversalTransition } from 'echarts/features';
|
import { LabelLayout, UniversalTransition } from 'echarts/features';
|
||||||
import { CanvasRenderer } from 'echarts/renderers';
|
import { CanvasRenderer } from 'echarts/renderers';
|
||||||
import { useElementSize } from '@vueuse/core';
|
import { useElementSize } from '@vueuse/core';
|
||||||
|
import { useThemeStore } from '@/store';
|
||||||
|
|
||||||
export type ECOption = echarts.ComposeOption<
|
export type ECOption = echarts.ComposeOption<
|
||||||
| BarSeriesOption
|
| BarSeriesOption
|
||||||
@ -57,20 +58,22 @@ echarts.use([
|
|||||||
/**
|
/**
|
||||||
* Echarts hooks函数
|
* Echarts hooks函数
|
||||||
* @param options - 图表配置
|
* @param options - 图表配置
|
||||||
* @param darkMode - 暗黑模式
|
|
||||||
* @param renderFun - 图表渲染函数(例如:图表监听函数)
|
* @param renderFun - 图表渲染函数(例如:图表监听函数)
|
||||||
* @description 按需引入图表组件,没注册的组件需要先引入
|
* @description 按需引入图表组件,没注册的组件需要先引入
|
||||||
*/
|
*/
|
||||||
export default function useEcharts(
|
export function useEcharts(
|
||||||
options: Ref<ECOption> | ComputedRef<ECOption>,
|
options: Ref<ECOption> | ComputedRef<ECOption>,
|
||||||
darkMode?: ComputedRef<boolean>,
|
|
||||||
renderFun?: (chartInstance: echarts.ECharts) => void
|
renderFun?: (chartInstance: echarts.ECharts) => void
|
||||||
) {
|
) {
|
||||||
let chart: echarts.ECharts | null = null;
|
const theme = useThemeStore();
|
||||||
|
|
||||||
const domRef = ref<HTMLElement | null>(null);
|
const domRef = ref<HTMLElement | null>(null);
|
||||||
|
|
||||||
const initialSize = { width: 0, height: 0 };
|
const initialSize = { width: 0, height: 0 };
|
||||||
const { width, height } = useElementSize(domRef, initialSize);
|
const { width, height } = useElementSize(domRef, initialSize);
|
||||||
|
|
||||||
|
let chart: echarts.ECharts | null = null;
|
||||||
|
|
||||||
function canRender() {
|
function canRender() {
|
||||||
return initialSize.width > 0 && initialSize.height > 0;
|
return initialSize.width > 0 && initialSize.height > 0;
|
||||||
}
|
}
|
||||||
@ -87,9 +90,9 @@ export default function useEcharts(
|
|||||||
|
|
||||||
async function render() {
|
async function render() {
|
||||||
if (domRef.value) {
|
if (domRef.value) {
|
||||||
const theme = darkMode?.value ? 'dark' : 'light';
|
const chartTheme = theme.darkMode ? 'dark' : 'light';
|
||||||
await nextTick();
|
await nextTick();
|
||||||
chart = echarts.init(domRef.value, theme);
|
chart = echarts.init(domRef.value, chartTheme);
|
||||||
if (renderFun) {
|
if (renderFun) {
|
||||||
renderFun(chart);
|
renderFun(chart);
|
||||||
}
|
}
|
||||||
@ -110,7 +113,7 @@ export default function useEcharts(
|
|||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
|
||||||
watch([width, height], ([newWidth, newHeight]) => {
|
const stopSizeWatch = watch([width, height], ([newWidth, newHeight]) => {
|
||||||
initialSize.width = newWidth;
|
initialSize.width = newWidth;
|
||||||
initialSize.height = newHeight;
|
initialSize.height = newHeight;
|
||||||
if (canRender()) {
|
if (canRender()) {
|
||||||
@ -122,16 +125,22 @@ export default function useEcharts(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(options, newValue => {
|
const stopOptionWatch = watch(options, newValue => {
|
||||||
update(newValue);
|
update(newValue);
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(darkMode || computed(() => false), () => {
|
const stopDarkModeWatch = watch(
|
||||||
updateTheme();
|
() => theme.darkMode,
|
||||||
});
|
() => {
|
||||||
|
updateTheme();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
destroy();
|
destroy();
|
||||||
|
stopSizeWatch();
|
||||||
|
stopOptionWatch();
|
||||||
|
stopDarkModeWatch();
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
@ -1,3 +1,4 @@
|
|||||||
export * from './system';
|
export * from './system';
|
||||||
export * from './router';
|
export * from './router';
|
||||||
export * from './layout';
|
export * from './layout';
|
||||||
|
export * from './echarts';
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import useEcharts from './useEcharts';
|
|
||||||
import useCountDown from './useCountDown';
|
import useCountDown from './useCountDown';
|
||||||
import useSmsCode from './useSmsCode';
|
import useSmsCode from './useSmsCode';
|
||||||
import useImageVerify from './useImageVerify';
|
import useImageVerify from './useImageVerify';
|
||||||
|
|
||||||
export { useEcharts, useCountDown, useSmsCode, useImageVerify };
|
export { useCountDown, useSmsCode, useImageVerify };
|
||||||
|
|
||||||
export * from './useEcharts';
|
|
||||||
|
1
src/typings/route.d.ts
vendored
1
src/typings/route.d.ts
vendored
@ -40,6 +40,7 @@ declare namespace AuthRoute {
|
|||||||
| 'plugin_charts_echarts'
|
| 'plugin_charts_echarts'
|
||||||
| 'plugin_charts_d3'
|
| 'plugin_charts_d3'
|
||||||
| 'plugin_charts_antv'
|
| 'plugin_charts_antv'
|
||||||
|
| 'plugin_charts_chartjs'
|
||||||
| 'auth-demo'
|
| 'auth-demo'
|
||||||
| 'auth-demo_permission'
|
| 'auth-demo_permission'
|
||||||
| 'auth-demo_super'
|
| 'auth-demo_super'
|
||||||
|
@ -31,13 +31,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useThemeStore } from '@/store';
|
import { useEcharts, type ECOption } from '@/composables';
|
||||||
import { useEcharts, type ECOption } from '@/hooks';
|
|
||||||
|
|
||||||
const theme = useThemeStore();
|
|
||||||
|
|
||||||
const darkMode = computed(() => theme.darkMode);
|
|
||||||
|
|
||||||
const lineOptions = ref<ECOption>({
|
const lineOptions = ref<ECOption>({
|
||||||
tooltip: {
|
tooltip: {
|
||||||
@ -133,7 +128,7 @@ const lineOptions = ref<ECOption>({
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
const { domRef: lineRef } = useEcharts(lineOptions, darkMode);
|
const { domRef: lineRef } = useEcharts(lineOptions);
|
||||||
|
|
||||||
const pieOptions = ref<ECOption>({
|
const pieOptions = ref<ECOption>({
|
||||||
tooltip: {
|
tooltip: {
|
||||||
@ -180,7 +175,7 @@ const pieOptions = ref<ECOption>({
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
const { domRef: pieRef } = useEcharts(pieOptions, darkMode);
|
const { domRef: pieRef } = useEcharts(pieOptions);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
@ -16,13 +16,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed } from 'vue';
|
import { ref } from 'vue';
|
||||||
import { useThemeStore } from '@/store';
|
import { useEcharts, type ECOption } from '@/composables';
|
||||||
import { useEcharts, type ECOption } from '@/hooks';
|
|
||||||
|
|
||||||
const theme = useThemeStore();
|
|
||||||
|
|
||||||
const darkMode = computed(() => theme.darkMode);
|
|
||||||
|
|
||||||
const pieOptions = ref<ECOption>({
|
const pieOptions = ref<ECOption>({
|
||||||
legend: {},
|
legend: {},
|
||||||
@ -58,7 +53,7 @@ const pieOptions = ref<ECOption>({
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
const { domRef: pieRef } = useEcharts(pieOptions, darkMode);
|
const { domRef: pieRef } = useEcharts(pieOptions);
|
||||||
|
|
||||||
const lineOptions = ref<ECOption>({
|
const lineOptions = ref<ECOption>({
|
||||||
tooltip: {
|
tooltip: {
|
||||||
@ -70,8 +65,26 @@ const lineOptions = ref<ECOption>({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
title: {
|
||||||
|
text: 'Stacked Line'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine']
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '3%',
|
||||||
|
right: '4%',
|
||||||
|
bottom: '3%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
toolbox: {
|
||||||
|
feature: {
|
||||||
|
saveAsImage: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
type: 'category',
|
type: 'category',
|
||||||
|
boundaryGap: false,
|
||||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: {
|
||||||
@ -79,13 +92,158 @@ const lineOptions = ref<ECOption>({
|
|||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
data: [820, 932, 901, 934, 1290, 1330, 1320],
|
color: '#37a2da',
|
||||||
|
name: 'Email',
|
||||||
type: 'line',
|
type: 'line',
|
||||||
smooth: true
|
smooth: true,
|
||||||
|
stack: 'Total',
|
||||||
|
areaStyle: {
|
||||||
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{
|
||||||
|
offset: 0.25,
|
||||||
|
color: '#37a2da'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: '#fff'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: [120, 132, 101, 134, 90, 230, 210]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color: '#9fe6b8',
|
||||||
|
name: 'Union Ads',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
stack: 'Total',
|
||||||
|
areaStyle: {
|
||||||
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{
|
||||||
|
offset: 0.25,
|
||||||
|
color: '#9fe6b8'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: '#fff'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: [220, 182, 191, 234, 290, 330, 310]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color: '#fedb5c',
|
||||||
|
name: 'Video Ads',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
stack: 'Total',
|
||||||
|
areaStyle: {
|
||||||
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{
|
||||||
|
offset: 0.25,
|
||||||
|
color: '#fedb5c'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: '#fff'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: [150, 232, 201, 154, 190, 330, 410]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color: '#fb7293',
|
||||||
|
name: 'Direct',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
stack: 'Total',
|
||||||
|
areaStyle: {
|
||||||
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{
|
||||||
|
offset: 0.25,
|
||||||
|
color: '#fb7293'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: '#fff'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: [320, 332, 301, 334, 390, 330, 320]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
color: '#e7bcf3',
|
||||||
|
name: 'Search Engine',
|
||||||
|
type: 'line',
|
||||||
|
smooth: true,
|
||||||
|
stack: 'Total',
|
||||||
|
areaStyle: {
|
||||||
|
color: {
|
||||||
|
type: 'linear',
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 0,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [
|
||||||
|
{
|
||||||
|
offset: 0.25,
|
||||||
|
color: '#e7bcf3'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: '#fff'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
focus: 'series'
|
||||||
|
},
|
||||||
|
data: [820, 932, 901, 934, 1290, 1330, 1320]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
const { domRef: lineRef } = useEcharts(lineOptions, darkMode);
|
const { domRef: lineRef } = useEcharts(lineOptions);
|
||||||
|
|
||||||
const barOptions = ref<ECOption>({
|
const barOptions = ref<ECOption>({
|
||||||
tooltip: {
|
tooltip: {
|
||||||
@ -108,6 +266,7 @@ const barOptions = ref<ECOption>({
|
|||||||
{
|
{
|
||||||
data: [120, 200, 150, 80, 70, 110, 130],
|
data: [120, 200, 150, 80, 70, 110, 130],
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
|
color: '#8378ea',
|
||||||
showBackground: true,
|
showBackground: true,
|
||||||
backgroundStyle: {
|
backgroundStyle: {
|
||||||
color: 'rgba(180, 180, 180, 0.2)'
|
color: 'rgba(180, 180, 180, 0.2)'
|
||||||
@ -115,7 +274,7 @@ const barOptions = ref<ECOption>({
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
const { domRef: barRef } = useEcharts(barOptions, darkMode);
|
const { domRef: barRef } = useEcharts(barOptions);
|
||||||
|
|
||||||
const scatterOptions = ref<ECOption>({
|
const scatterOptions = ref<ECOption>({
|
||||||
tooltip: {},
|
tooltip: {},
|
||||||
@ -148,12 +307,13 @@ const scatterOptions = ref<ECOption>({
|
|||||||
[7.08, 5.82],
|
[7.08, 5.82],
|
||||||
[5.02, 5.68]
|
[5.02, 5.68]
|
||||||
],
|
],
|
||||||
|
color: '#fedb5c',
|
||||||
type: 'scatter'
|
type: 'scatter'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
const { domRef: scatterRef } = useEcharts(scatterOptions, darkMode);
|
const { domRef: scatterRef } = useEcharts(scatterOptions);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
Loading…
Reference in New Issue
Block a user