feat: 重构订单簿组件以使用 WebSocket 订阅实时数据,优化数据更新逻辑
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user