fix(图表): 修复组件卸载时图表内存泄漏问题

添加组件挂载状态跟踪,确保在组件卸载时正确清理图表实例
移除无用注释,修正描述文字
This commit is contained in:
2025-10-14 18:58:30 +08:00
parent 73c84f7b8d
commit a6f4c96f1f
4 changed files with 43 additions and 22 deletions

View File

@@ -27,18 +27,25 @@ const contextPanelRef = ref(null);
const sentimentChartCanvas = ref(null);
const chartInstances = {};
// 添加组件挂载状态跟踪
const isComponentMounted = ref(true);
// CHARTING
const createOrUpdateChart = (chartId, canvasRef, config) => {
if (chartInstances[chartId]) {
chartInstances[chartId].destroy();
}
if (canvasRef.value) {
// 确保组件仍然挂载且canvas引用存在
if (isComponentMounted.value && canvasRef.value) {
const ctx = canvasRef.value.getContext('2d');
chartInstances[chartId] = new Chart(ctx, config);
}
};
const renderSentimentChart = (history) => {
// 确保组件仍然挂载
if (!isComponentMounted.value) return;
if (!sentimentChartCanvas.value) return;
const ctx = sentimentChartCanvas.value.getContext('2d');
const gradient = ctx.createLinearGradient(0, 0, 0, 120);
@@ -126,6 +133,21 @@ watch(() => props.selectedContact, (newContact) => {
});
}
}, { immediate: true });
// LIFECYCLE HOOKS
onMounted(() => {
isComponentMounted.value = true;
});
onBeforeUnmount(() => {
isComponentMounted.value = false;
// 清理所有图表实例
Object.values(chartInstances).forEach(chart => {
if (chart) {
chart.destroy();
}
});
});
</script>
<style lang="scss" scoped>

View File

@@ -28,7 +28,7 @@ const props = defineProps({
})
// 组件状态跟踪
let isComponentMounted = true
const isComponentMounted = ref(true)
// Chart.js 实例
const chartInstances = {}
@@ -44,13 +44,13 @@ const funnelData = reactive({
// 监听teamSalesFunnel变化并更新图表数据
watch(() => props.teamSalesFunnel, (newVal) => {
if (newVal && Object.keys(newVal).length > 0 && isComponentMounted) {
if (newVal && Object.keys(newVal).length > 0 && isComponentMounted.value) {
// 按照固定顺序提取数据
const order = ['线索', '加微', '到课', '定金', '成交']
funnelData.data = order.map(key => newVal[key] || 0)
// 确保在DOM更新后再更新图表
nextTick(() => {
if (isComponentMounted) {
if (isComponentMounted.value) {
renderPersonalFunnelChart()
}
})
@@ -94,19 +94,19 @@ const renderPersonalFunnelChart = () => {
// 生命周期钩子
onMounted(() => {
isComponentMounted = true
isComponentMounted.value = true
// 处理初始传入的teamSalesFunnel数据
if (props.teamSalesFunnel && Object.keys(props.teamSalesFunnel).length > 0) {
const order = ['线索', '加微', '到课', '定金', '成交']
funnelData.data = order.map(key => props.teamSalesFunnel[key] || 0)
}
if (isComponentMounted) {
if (isComponentMounted.value) {
renderPersonalFunnelChart()
}
})
onBeforeUnmount(() => {
isComponentMounted = false
isComponentMounted.value = false
Object.values(chartInstances).forEach(chart => chart.destroy())
})
</script>