Skip to content

渲染数据在计算中时最佳实践 ​

本节目标:理解“渲染数据在计算中时最佳实践”的核心思路,并能把它用于实际开发或面试表达。 最佳实践 以下是基于 Exness 场景(大订单量、Vue 3、表格渲染)的 Web Worker 数据展示最佳实践: 3.1 管理加载状态

  • 实践:
    • 扩展 loading 状态,覆盖 useFetch 和 Worker 处理。
    • 添加 workerLoading 状态,跟踪 Worker 的异步处理。
  • 代码: const workerLoading = ref(false);watch(_data, (newData) => { if (!newData) return; workerLoading.value = true; // 开始 Worker 处理 const rawMap = isMap(newData as OrderResp) ? toRaw((newData as OrderMapResp).data) : { all: toRaw((newData as OrderListResp).data) }; worker.postMessage({ type: 'processOrders', data: { rawMap, isFoldMode: isFoldMode.value } });});worker.onmessage = (event: MessageEvent) => { const { type, data } = event.data as WorkerMessage; if (type === 'processedOrders') { unfoldRowMap.value = data.unfoldRowMap; foldRowMap.value = data.foldRowMap; unfoldList.value = data.unfoldList; foldList.value = data.foldList; stats.value = data.stats; totalFloatingPL.value = data.totalFloatingPL; totalCommission.value = data.totalCommission; workerLoading.value = false; // Worker 处理完成 } else if (type === 'error') { console.error('Worker 错误:', data.message); workerLoading.value = false; }};// 综合加载状态_const isLoading = computed(() => loading.value || workerLoading.value);

3.2 使用 Skeleton 组件

  • 实践:
    • 在初次加载或账户切换时,显示 Skeleton 表格。
    • 使用 v-if 切换 Skeleton 和真实数据。
  • 代码(OpenOrder.vue 示例): <template> <div> <template v-if="isLoading && !data.length"> <!-- Skeleton --> <el-table :data="Array(10).fill({})" style="width: 100%"> <el-table-column prop="SYMBOL" label="Symbol"> <template #default> <el-skeleton-item variant="text" style="width: 80px" /> </template> </el-table-column> <el-table-column prop="PROFIT" label="Profit"> <template #default> <el-skeleton-item variant="text" style="width: 60px" /> </template> </el-table-column> <!-- 其他列 --> </el-table> </template> <el-table v-else :data="data" style="width: 100%"> <el-table-column prop="SYMBOL" label="Symbol" /> <el-table-column prop="OPEN_PRICE" label="Open Price" /> <el-table-column prop="CURRENT_PRICE" label="Current Price" /> <el-table-column prop="PROFIT" label="Profit" /> <el-table-column prop="VOLUME" label="Volume" /> </el-table> </div></template><script setup>import { useOpenOrder } from './useOpenOrder';import { ref } from 'vue';const accountInfo = ref({ name: 'exness', loginid: '123' });const { data, isLoading } = useOpenOrder(accountInfo);</script>
  • 说明:
    • 使用 Element Plus 的 <el-skeleton-item> 或自定义 Skeleton。
    • 条件:isLoading && !data.length 确保初次加载显示 Skeleton,后续更新显示旧数据。

3.3 保留旧数据

  • 实践:
    • 在 Worker 处理期间,保留 foldList 或 unfoldList 的旧值。
    • 实时更新价格(newQuotePayload)保持表格活跃。
  • 代码(已有逻辑支持):
    • 当前代码已使用 shallowRef 和 ref 管理 foldList/unfoldList,默认保留旧值。
    • watch(tradeStore.newQuotePayload, ...) 实时更新 CURRENT_PRICE 和 PL,无需修改。
  • 优化:
    • 确保 workerLoading 不清空 foldList/unfoldList: worker.onmessage = (event: MessageEvent) => { if (type === 'processedOrders') { // 仅更新非空数据 if (data.unfoldList?.length) unfoldList.value = data.unfoldList; if (data.foldList?.length) foldList.value = data.foldList; workerLoading.value = false; }};

3.4 优化表格渲染

  • 实践:
    • 使用虚拟滚动(如 el-table-v2)处理大订单量。
    • 分页或懒加载减少 DOM 节点。
  • 代码: <el-table-v2 :columns="[ { key: 'SYMBOL', title: 'Symbol', dataKey: 'SYMBOL' }, { key: 'PROFIT', title: 'Profit', dataKey: 'PROFIT' }, ]" :data="data" :width="800" :height="600" :row-height="40"/>
  • 说明:
    • el-table-v2 是 Element Plus 的虚拟滚动表格,适合 20,000+ 条数据。
    • 动态调整 pageSize(当前为 9999),分批加载。

3.5 错误处理

  • 实践:
    • 显示错误提示(如 Worker 报错或 API 失败)。
    • 提供重试按钮。
  • Code: <template> <div> <el-alert v-if="error" type="error" :title="error" show-icon> <el-button @click="fetchData">Retry</el-button> </el-alert> <el-table v-else-if="!isLoading || data.length" :data="data"> <!-- 表格内容 --> </el-table> <el-skeleton v-else /> </div></template><script setup>const { data, isLoading, fetchData, error } = useOpenOrder(accountInfo);</script>

3.6 实时更新提示

  • 实践:
    • 显示 totalFloatingPL 和 stats 的实时变化(如颜色闪烁)。
    • 使用节流(已有 useThrottle)避免频繁更新。
  • Code: <div>总盈亏: <span :class="{ 'text-green': throttledTotalPL > 0 }">{{ throttledTotalPL }}</span></div>

本站总访问 — 次