同步6/16

This commit is contained in:
Zy
2026-06-01 18:12:58 +08:00
parent 38274ab612
commit 50e7b14fd6
183 changed files with 8956 additions and 4803 deletions

View File

@@ -3,7 +3,7 @@
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue';
import { ref, onMounted, onBeforeUnmount, watch, nextTick, shallowRef } from 'vue';
import * as echarts from 'echarts';
import type { EChartsOption, ECharts } from 'echarts';
@@ -19,7 +19,6 @@ interface Props {
const props = withDefaults(defineProps<Props>(), {
width: '100%',
height: '100%',
options: () => ({}) as EChartsOption,
theme: '',
autoResize: true,
immediate: true
@@ -27,36 +26,38 @@ const props = withDefaults(defineProps<Props>(), {
const emit = defineEmits<{
ready: [chart: ECharts];
click: [params: any];
click: [params: echarts.ECElementEvent];
rendered: [];
}>();
const chartRef = ref<HTMLDivElement>();
let chartInstance: ECharts | null = null;
// 3. 使用 shallowRef 优化性能,因为 ECharts 实例不需要深层响应式
const chartInstance = shallowRef<ECharts | null>(null);
let resizeObserver: ResizeObserver | null = null;
const initChart = () => {
if (!chartRef.value) return;
if (chartInstance) {
chartInstance.dispose();
chartInstance = null;
if (chartInstance.value) {
chartInstance.value.dispose();
chartInstance.value = null;
}
chartInstance = echarts.init(chartRef.value, props.theme);
chartInstance.setOption(props.options);
const instance = echarts.init(chartRef.value, props.theme);
chartInstance.value = instance;
chartInstance.value.setOption(props.options);
emit('ready', chartInstance);
emit('ready', instance);
emit('rendered');
chartInstance.on('click', (params: any) => {
instance.on('click', (params: any) => {
emit('click', params);
});
};
const updateChart = () => {
if (chartInstance) {
chartInstance.setOption(props.options, {
if (chartInstance.value) {
chartInstance.value.setOption(props.options, {
notMerge: false,
lazyUpdate: false
});
@@ -66,15 +67,15 @@ const updateChart = () => {
// ✅ 核心修复:支持 scale 缩放后重绘
const resizeChart = () => {
if (!chartInstance) return;
chartInstance.resize();
if (!chartInstance.value) return;
chartInstance.value.resize();
};
const getInstance = () => chartInstance;
const getInstance = () => chartInstance.value;
const exportAsImage = (type: 'png' | 'svg' | 'jpeg' = 'png') => {
return (
chartInstance?.getDataURL({
chartInstance.value?.getDataURL({
type,
pixelRatio: 2,
backgroundColor: '#fff'
@@ -86,23 +87,18 @@ watch(() => props.options, updateChart, { deep: true });
onMounted(() => {
nextTick(() => initChart());
if (props.autoResize && chartRef.value) {
resizeObserver = new ResizeObserver(resizeChart);
resizeObserver.observe(chartRef.value);
}
});
// ✅ 关键:监听 window.resize(scale 缩放会触发 window.resize)
onMounted(() => {
window.addEventListener('resize', resizeChart);
});
onBeforeUnmount(() => {
window.removeEventListener('resize', resizeChart);
resizeObserver?.disconnect();
chartInstance?.dispose();
chartInstance = null;
chartInstance.value?.dispose();
chartInstance.value = null;
});
defineExpose({