!353 fix(bpm): clean up BPMN viewer resize observer

Merge pull request !353 from 芋道源码/dev
master v2026.05
芋道源码 2026-05-31 13:50:10 +00:00 committed by Gitee
commit 72aac700ff
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
3 changed files with 129 additions and 3 deletions

View File

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { h, onBeforeUnmount, onMounted, ref, watch } from 'vue'; import { h, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { BpmProcessInstanceStatus, DICT_TYPE } from '@vben/constants'; import { BpmProcessInstanceStatus, DICT_TYPE } from '@vben/constants';
import { UndoOutlined, ZoomInOutlined, ZoomOutOutlined } from '@vben/icons'; import { UndoOutlined, ZoomInOutlined, ZoomOutOutlined } from '@vben/icons';
@ -45,6 +45,41 @@ const processReZoom = () => {
bpmnViewer.value?.get('canvas').zoom('fit-viewport', 'auto'); bpmnViewer.value?.get('canvas').zoom('fit-viewport', 'auto');
}; };
let resizeObserver: null | ResizeObserver = null;
/** 停止 ResizeObserver */
const stopResizeObserver = () => {
if (resizeObserver) {
resizeObserver.disconnect();
resizeObserver = null;
}
};
/** 启动 ResizeObserver 监听容器尺寸变化 */
const startResizeObserver = () => {
stopResizeObserver();
if (!processCanvas.value || !bpmnViewer.value) {
return;
}
const { clientHeight, clientWidth } = processCanvas.value;
if (clientWidth > 0 && clientHeight > 0) {
processReZoom();
return;
}
resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
const { height, width } = entry.contentRect;
if (width > 0 && height > 0 && bpmnViewer.value) {
processReZoom();
stopResizeObserver();
}
}
});
resizeObserver.observe(processCanvas.value);
};
/** Zoom放大 */ /** Zoom放大 */
const processZoomIn = (zoomStep = 0.1) => { const processZoomIn = (zoomStep = 0.1) => {
const newZoom = Math.floor(defaultZoom.value * 100 + zoomStep * 100) / 100; const newZoom = Math.floor(defaultZoom.value * 100 + zoomStep * 100) / 100;
@ -71,6 +106,7 @@ const processZoomOut = (zoomStep = 0.1) => {
/** 流程图预览清空 */ /** 流程图预览清空 */
const clearViewer = () => { const clearViewer = () => {
stopResizeObserver();
if (processCanvas.value) { if (processCanvas.value) {
processCanvas.value.innerHTML = ''; processCanvas.value.innerHTML = '';
} }
@ -157,6 +193,12 @@ const importXML = async (xml: string) => {
isLoading.value = false; isLoading.value = false;
// //
setProcessStatus(props.view); setProcessStatus(props.view);
// ResizeObserver
// https://github.com/yudaocode/yudao-ui-admin-vue3/pull/221
if (bpmnViewer.value) {
await nextTick();
startResizeObserver();
}
} }
} }
}; };

View File

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { h, onBeforeUnmount, onMounted, ref, watch } from 'vue'; import { h, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { BpmProcessInstanceStatus, DICT_TYPE } from '@vben/constants'; import { BpmProcessInstanceStatus, DICT_TYPE } from '@vben/constants';
import { UndoOutlined, ZoomInOutlined, ZoomOutOutlined } from '@vben/icons'; import { UndoOutlined, ZoomInOutlined, ZoomOutOutlined } from '@vben/icons';
@ -45,6 +45,41 @@ const processReZoom = () => {
bpmnViewer.value?.get('canvas').zoom('fit-viewport', 'auto'); bpmnViewer.value?.get('canvas').zoom('fit-viewport', 'auto');
}; };
let resizeObserver: null | ResizeObserver = null;
/** 停止 ResizeObserver */
const stopResizeObserver = () => {
if (resizeObserver) {
resizeObserver.disconnect();
resizeObserver = null;
}
};
/** 启动 ResizeObserver 监听容器尺寸变化 */
const startResizeObserver = () => {
stopResizeObserver();
if (!processCanvas.value || !bpmnViewer.value) {
return;
}
const { clientHeight, clientWidth } = processCanvas.value;
if (clientWidth > 0 && clientHeight > 0) {
processReZoom();
return;
}
resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
const { height, width } = entry.contentRect;
if (width > 0 && height > 0 && bpmnViewer.value) {
processReZoom();
stopResizeObserver();
}
}
});
resizeObserver.observe(processCanvas.value);
};
/** Zoom放大 */ /** Zoom放大 */
const processZoomIn = (zoomStep = 0.1) => { const processZoomIn = (zoomStep = 0.1) => {
const newZoom = Math.floor(defaultZoom.value * 100 + zoomStep * 100) / 100; const newZoom = Math.floor(defaultZoom.value * 100 + zoomStep * 100) / 100;
@ -71,6 +106,7 @@ const processZoomOut = (zoomStep = 0.1) => {
/** 流程图预览清空 */ /** 流程图预览清空 */
const clearViewer = () => { const clearViewer = () => {
stopResizeObserver();
if (processCanvas.value) { if (processCanvas.value) {
processCanvas.value.innerHTML = ''; processCanvas.value.innerHTML = '';
} }
@ -157,6 +193,12 @@ const importXML = async (xml: string) => {
isLoading.value = false; isLoading.value = false;
// //
setProcessStatus(props.view); setProcessStatus(props.view);
// ResizeObserver
// https://github.com/yudaocode/yudao-ui-admin-vue3/pull/221
if (bpmnViewer.value) {
await nextTick();
startResizeObserver();
}
} }
} }
}; };

View File

@ -1,5 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'; import { nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue';
import { BpmProcessInstanceStatus, DICT_TYPE } from '@vben/constants'; import { BpmProcessInstanceStatus, DICT_TYPE } from '@vben/constants';
import { UndoOutlined, ZoomInOutlined, ZoomOutOutlined } from '@vben/icons'; import { UndoOutlined, ZoomInOutlined, ZoomOutOutlined } from '@vben/icons';
@ -52,6 +52,41 @@ const processReZoom = () => {
bpmnViewer.value?.get('canvas').zoom('fit-viewport', 'auto'); bpmnViewer.value?.get('canvas').zoom('fit-viewport', 'auto');
}; };
let resizeObserver: null | ResizeObserver = null;
/** 停止 ResizeObserver */
const stopResizeObserver = () => {
if (resizeObserver) {
resizeObserver.disconnect();
resizeObserver = null;
}
};
/** 启动 ResizeObserver 监听容器尺寸变化 */
const startResizeObserver = () => {
stopResizeObserver();
if (!processCanvas.value || !bpmnViewer.value) {
return;
}
const { clientHeight, clientWidth } = processCanvas.value;
if (clientWidth > 0 && clientHeight > 0) {
processReZoom();
return;
}
resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
const { height, width } = entry.contentRect;
if (width > 0 && height > 0 && bpmnViewer.value) {
processReZoom();
stopResizeObserver();
}
}
});
resizeObserver.observe(processCanvas.value);
};
/** Zoom放大 */ /** Zoom放大 */
const processZoomIn = (zoomStep = 0.1) => { const processZoomIn = (zoomStep = 0.1) => {
const newZoom = Math.floor(defaultZoom.value * 100 + zoomStep * 100) / 100; const newZoom = Math.floor(defaultZoom.value * 100 + zoomStep * 100) / 100;
@ -78,6 +113,7 @@ const processZoomOut = (zoomStep = 0.1) => {
/** 流程图预览清空 */ /** 流程图预览清空 */
const clearViewer = () => { const clearViewer = () => {
stopResizeObserver();
if (processCanvas.value) { if (processCanvas.value) {
processCanvas.value.innerHTML = ''; processCanvas.value.innerHTML = '';
} }
@ -164,6 +200,12 @@ const importXML = async (xml: string) => {
isLoading.value = false; isLoading.value = false;
// //
setProcessStatus(props.view); setProcessStatus(props.view);
// ResizeObserver
// https://github.com/yudaocode/yudao-ui-admin-vue3/pull/221
if (bpmnViewer.value) {
await nextTick();
startResizeObserver();
}
} }
} }
}; };