fix(frontend): EquityCurve 去 v-if + watch flush:post(治净值图永不init)
CI/CD / test (push) Successful in 9s
CI/CD / nas-deploy (push) Successful in 22s
CI/CD / nas-verify (push) Successful in 2s

EquityCurve 用 v-if/v-else(空数据占位/否则chart-box),但数据异步到达时 v-else 切换 + watch 默认 pre flush → el.value 尚未绑定 → echarts.init 跳过 → 净值图 hasEchartsInstance=false 永不画。改为总渲染 chart-box(同 BenchmarkCurve 模式) + watch flush:post 保证 DOM patch 后 render。vue-tsc RC=0。
This commit is contained in:
2026-08-02 20:01:55 +08:00
parent c049e0e97d
commit 4c5270cf7a
@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, onMounted, watch } from 'vue' import { ref, onMounted, watch } from 'vue'
import type { EChartsCoreOption } from 'echarts' import type { EChartsCoreOption } from 'echarts'
import { useChart } from '@/composables/useChart' import { useChart } from '@/composables/useChart'
import { darkTitle, darkTooltip, darkGrid, darkAxis } from '@/utils/echartsDark' import { darkTitle, darkTooltip, darkGrid, darkAxis } from '@/utils/echartsDark'
@@ -7,14 +7,16 @@ import { darkTitle, darkTooltip, darkGrid, darkAxis } from '@/utils/echartsDark'
// 净值曲线(独立组件)。数据源 equity-curve 接口 = BacktestResult.equity_curve, // 净值曲线(独立组件)。数据源 equity-curve 接口 = BacktestResult.equity_curve,
// 不依赖 *_metrics.json(CTA 引擎当前未生成该文件,致 BenchmarkCurve 等图全空)。 // 不依赖 *_metrics.json(CTA 引擎当前未生成该文件,致 BenchmarkCurve 等图全空)。
// 零成交时净值是 N 天平线(初始资金不变),也要画出而非空白。 // 零成交时净值是 N 天平线(初始资金不变),也要画出而非空白。
//
// 模板总渲染 chart-box(无 v-if): 否则数据异步到达时 v-else 切换 + watch 默认 pre
// flush 时机下 el.value 尚未绑定 → ensureChart 跳过 → echarts 永不 init → 净值图空白。
// watch 加 flush:'post' 进一步保证 DOM patch 后再 render。
const props = defineProps<{ dates: string[]; equity: number[] }>() const props = defineProps<{ dates: string[]; equity: number[] }>()
const el = ref<HTMLDivElement>() const el = ref<HTMLDivElement>()
const { setOption } = useChart(el) const { setOption } = useChart(el)
const isEmpty = computed(() => !props.dates.length || !props.equity.length)
function render(): void { function render(): void {
if (isEmpty.value) return if (!props.dates.length || !props.equity.length) return
const option: EChartsCoreOption = { const option: EChartsCoreOption = {
title: darkTitle('净值曲线'), title: darkTitle('净值曲线'),
tooltip: darkTooltip(), tooltip: darkTooltip(),
@@ -37,23 +39,13 @@ function render(): void {
} }
onMounted(render) onMounted(render)
watch(() => [props.dates, props.equity], render, { deep: true }) watch(() => [props.dates, props.equity], render, { deep: true, flush: 'post' })
</script> </script>
<template> <template>
<div v-if="isEmpty" class="chart-empty">暂无净值数据</div> <div ref="el" class="chart-box" />
<div v-else ref="el" class="chart-box" />
</template> </template>
<style scoped> <style scoped>
.chart-box { width: 100%; height: 320px; } .chart-box { width: 100%; height: 320px; }
.chart-empty {
width: 100%;
height: 320px;
display: flex;
align-items: center;
justify-content: center;
color: #8b949e;
font-size: 13px;
}
</style> </style>