feat: 重构订单簿组件以使用 WebSocket 订阅实时数据,优化数据更新逻辑

This commit is contained in:
2026-01-14 01:58:36 +07:00
parent a547f00306
commit a64bd9b470

View File

@@ -1,9 +1,23 @@
<script lang='ts' setup> <script lang='ts' setup>
import { client, safeClient } from "@/api"; import { tradeWebSocket } from "@/tradingview/websocket";
interface Item {
asks: Array<{
price: string;
size: string;
}>;
bids: Array<{
price: string;
size: string;
}>;
}
const props = defineProps<{ symbol: string }>(); const props = defineProps<{ symbol: string }>();
const { data } = await safeClient(client.api.trading_pairs.orderbook.get({ query: { symbol: props.symbol, depth: 30 } })); const data = ref<Item>({
asks: [],
bids: [],
});
// 计算买单和卖单的最大数量,用于计算占比 // 计算买单和卖单的最大数量,用于计算占比
const maxBidAmount = computed(() => { const maxBidAmount = computed(() => {
@@ -38,6 +52,52 @@ function formatPrice(price: string) {
function formatAmount(amount: string) { function formatAmount(amount: string) {
return Number(amount).toFixed(4); return Number(amount).toFixed(4);
} }
function subscribe() {
tradeWebSocket.subscribeChannel([{
name: "depth",
symbol: props.symbol,
}]);
}
function unsubscribe() {
useTimeoutFn(() => {
console.log("unsubscribe order book: ", props.symbol);
tradeWebSocket.unsubscribeChannel([{
name: "depth",
symbol: props.symbol,
}]);
}, 3000);
}
// 监听订单簿更新
tradeWebSocket.subscribe((message) => {
if ("bids" in message.data) {
if (!data.value?.bids.length) {
data.value!.bids = [];
}
data.value!.bids.splice(0, data.value!.bids.length, ...message.data.bids);
}
if ("asks" in message.data) {
if (!data.value?.asks.length) {
data.value!.asks = [];
}
data.value!.asks.splice(0, data.value!.asks.length, ...message.data.asks);
}
});
watch(() => props.symbol, (newSymbol, oldSymbol) => {
if (newSymbol === oldSymbol)
return;
unsubscribe();
subscribe();
});
onMounted(() => {
subscribe();
});
onUnmounted(() => {
unsubscribe();
});
</script> </script>
<template> <template>
@@ -75,7 +135,7 @@ function formatAmount(amount: string) {
<!-- 数量 --> <!-- 数量 -->
<div class="relative z-1 text-right text-(--ion-color-step-600)"> <div class="relative z-1 text-right text-(--ion-color-step-600)">
{{ formatAmount(bid.quantity) }} {{ formatAmount(bid.size) }}
</div> </div>
</div> </div>
</div> </div>
@@ -113,7 +173,7 @@ function formatAmount(amount: string) {
<!-- 数量 --> <!-- 数量 -->
<div class="relative z-1 text-right text-(--ion-color-step-600)"> <div class="relative z-1 text-right text-(--ion-color-step-600)">
{{ formatAmount(ask.quantity) }} {{ formatAmount(ask.size) }}
</div> </div>
</div> </div>
</div> </div>