You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vuetify中VDataTable的横向滚动适配问题

解决v-data-table超出页面边界,实现横向滚动与自适应宽度

问题分析

你的AtomicDex OrderBook组件中,v-data-table因列内容过宽或布局限制导致溢出页面,无法在正常缩放比例下完整查看。核心问题是缺少横向滚动容器,且列宽未做合理约束。

解决方案步骤

1. 添加横向滚动容器

给每个v-data-table外层包裹一个带横向滚动样式的容器,让表格超出容器宽度时自动显示滚动条。

2. 优化布局组件约束

调整v-flex的响应式类,确保表格容器能充分利用可用宽度,避免不必要的限制。

3. 配置列宽(可选)

在表头配置中指定列宽,让列按比例分配宽度,防止某列过宽撑爆容器。

修改后的代码示例

<template>
  <v-card>
    <v-toolbar flat dense color="indigo">
      <v-toolbar-title>
        <span class="subheading">AtomicDEX order book</span>
      </v-toolbar-title>
      <div class="flex-grow-1"></div>
      <v-chip
        class="ma-2"
        color="white"
        outlined
        @click="refreshMarket()"
      >
        <v-icon left>mdi-server-plus</v-icon>Refresh
      </v-chip>
    </v-toolbar>

    <div v-if="marketdata.asks">
      <div class="table-scroll-container">
        <v-layout>
          <v-flex xs12> <!-- 修改为xs12,确保全宽度可用 -->
            <v-card-title>Asks</v-card-title>
            <v-data-table
              dense
              :sort-by="['price']"
              :sort-desc="[true]"
              :hide-default-footer="true"
              :headers="asksHeaders"
              :items="marketdata.asks"
              :items-per-page="-1"
              height="200px"
              class="elevation-1"
            >
              <template v-slot:column.price="{ header }">
                Price ({{wallets.rel.ticker }})
              </template>

              <template v-slot:column.maxvolume="{ header }">
                Amount ({{wallets.base.ticker }})
              </template>

              <template v-slot:column.relamount="{ header }">
                Total ({{wallets.rel.ticker }})
              </template>

              <template v-slot:item.price="{ item }"> {{ Number(Math.round(item.price+'e8')+'e-8') }}</template>

              <template v-slot:item.price2="{ item }">
                {{ Number(Math.round(item.price+'e8')+'e-8') }}
                <v-chip v-if="item.myOrder" x-small color="purple" dark>*</v-chip>
              </template> 

              <template v-slot:item.maxvolume="{ item }">
                {{ Number(Math.round(item.maxvolume+'e8')+'e-8') }}
              </template>
              <template v-slot:item.relamount="{ item }">
                {{ Number(Math.round(item.price*item.maxvolume+'e8')+'e-8') }}
              </template>
            </v-data-table>
          </v-flex>
        </v-layout>
      </div>
    </div>
    <div v-else>No current asks to display.</div>

    <h2 class="pl-3">{{ middlePriceSpreadData.middle }} Middle Price (Spread: {{ middlePriceSpreadData.spread}} %)</h2>

    <div v-if="marketdata.bids">
      <div class="table-scroll-container">
        <v-layout>
          <v-flex xs12> <!-- 修改为xs12,确保全宽度可用 -->
            <v-card-title>Bids</v-card-title>
            <v-data-table
              dense
              :sort-by="['price']"
              :sort-desc="[true]"
              hide-default-footer
              disable-pagination
              :headers="bidsHeaders"
              :items="marketdata.bids"
              :items-per-page="-1"
              height="200px"
            >
              <template v-slot:column.price="{ header }">
                Price ({{wallets.rel.ticker }})
              </template>

              <template v-slot:column.baseamount="{ header }">
                Amount ({{wallets.base.ticker }})
              </template>

              <template v-slot:column.maxvolume="{ header }">
                Total ({{wallets.rel.ticker }})
              </template>

              <template v-slot:item.price="{ item }">
                {{ Number(Math.round(item.price+'e8')+'e-8') }}
              </template>
              
              <template v-slot:item.price2="{ item }">
                {{ Number(Math.round(item.price+'e8')+'e-8') }}
                <v-chip v-if="item.myOrder" x-small color="purple" dark>*</v-chip>
              </template> 
              <template v-slot:item.baseamount="{ item }">
                {{ Number(Math.round(item.maxvolume/item.price+'e8')+'e-8') }}
              </template>
              <template v-slot:item.maxvolume="{ item }">
                {{ Number(Math.round(item.maxvolume+'e8')+'e-8') }}
              </template>
            </v-data-table>
          </v-flex>
        </v-layout>
      </div>
    </div>
    <div v-else>No current bids to display.</div>
  </v-card>
</template>

<style scoped>
.table-scroll-container {
  overflow-x: auto;
  width: 100%;
  padding: 0 16px; /* 可选,避免内容贴边 */
}
</style>

额外优化:配置表头列宽

如果希望列宽更均匀,可在asksHeaders和bidsHeaders数组中为每个表头添加width属性,例如:

// 示例asksHeaders配置
asksHeaders: [
  { text: 'Price', value: 'price', width: '33%' },
  { text: 'Amount', value: 'maxvolume', width: '33%' },
  { text: 'Total', value: 'relamount', width: '33%' }
]

改动说明

  • 新增table-scroll-container类,通过overflow-x: auto实现横向滚动
  • 将v-flex md lg改为v-flex xs12,确保表格容器在所有屏幕尺寸下都占满可用宽度
  • 可选的列宽配置让表格布局更可控,避免单列过宽导致溢出

内容的提问来源于stack exchange,提问作者artistAhmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 13:23:14