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

Vue3迁移后VDataTable无法移除分页及排序指示器不显示问题

Vuetify Labs VDataTable 迁移问题解决

我正在将旧Vue2项目迁移到Vite搭建的Vue3项目,使用Vuetify Labs的VDataTable组件时遇到两个问题:

  1. 无法移除分页功能;
  2. 数据表表头的默认排序指示器(hover时显示的样式)不显示。

当前组件代码

<v-card-title>Asks</v-card-title>
<div class="table-container">
<v-data-table
  dense
  :sort-by="sortBy"
  :headers="asksHeaders"
  :items="marketdata.asks"
  :rows-per-page="-1"
  options="disablePagination"
  class="elevation-1"
>
  <template v-slot:column.price="{ header }">
    <!-- {{ header.text.toUpperCase() }} -->
    Price ({{wallets.rel.ticker }})
  </template>

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

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

  <!-- Rounding from https://www.jacklmoore.com/notes/rounding-in-javascript/ -->
  <!-- Better to move to computed function for maintainability/non-repetitive -->
  <template v-slot:item.price="{ item }">
    {{ roundedPrice(item.columns.price) }}
  </template>

  <template v-slot:item.price2="{ item }">
    {{ roundedPrice(item.columns.price) }}
    <!-- Remaining code -->

    <!--
    better implementation handled in parent component on load of orders, then promise to set flag
    <v-chip v-if="hasMyOrder(item.price)" color="purple" dark>me</v-chip>
    -->
    <v-chip v-if="item.myOrder" x-small color="purple" dark>*</v-chip>
  </template> 

  <template v-slot:item.maxvolume="{ item }">
    {{ roundedPrice(item.columns.maxvolume) }}
  </template>

  <template v-slot:item.relamount="{ item }">
    {{ roundedPrice(item.columns.price * item.columns.maxvolume) }}
  </template>
  <template v-slot:bottom></template>
</v-data-table>
</div>

<script>
import { VDataTable } from 'vuetify/labs/VDataTable'

export default {
  name: "MarketData",
  props: ['wallets', 'marketdata', 'myOrdersThisMarket'],
  components: {
    VDataTable
  },
}
</script>

项目依赖版本

{
  "name": "mm2v3",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "serve": "vite preview",
    "build": "vite build",
    "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore",
    "dev": "vite",
    "host": "vite --host",
    "format": "prettier --write src/",
    "preview": "vite preview"
  },
  "dependencies": {
    "@mdi/font": "5.9.55",
    "axios": "^1.3.4",
    "pinia": "^2.0.32",
    "qrcode.vue": "^3.3.4",
    "roboto-fontface": "*",
    "vue": "^3.2.47",
    "vue-router": "^4.1.6",
    "vuetify": "npm:@vuetify/nightly@next",
    "webfontloader": "^1.0.0"
  },
  "devDependencies": {
    "@rushstack/eslint-patch": "^1.2.0",
    "@vitejs/plugin-vue": "^4.0.0",
    "@vitejs/plugin-vue-jsx": "^3.0.0",
    "@vue/eslint-config-prettier": "^7.1.0",
    "eslint": "^8.34.0",
    "eslint-plugin-vue": "^9.9.0",
    "prettier": "^2.8.4",
    "vite": "^4.1.4",
    "vite-plugin-vuetify": "^1.0.0-alpha.12",
    "vue-cli-plugin-vuetify": "~2.5.8"
  }
}

问题1:移除分页功能

当前写法options="disablePagination"和:rows-per-page="-1"不符合Vuetify Labs VDataTable的API规范,正确做法是:

  • 使用:items-per-page="-1"禁用分页逻辑
  • 添加hide-default-footer属性隐藏底部分页栏
  • 删掉无用的<template v-slot:bottom></template>

修改后的组件标签:

<v-data-table
  dense
  :sort-by="sortBy"
  :headers="asksHeaders"
  :items="marketdata.asks"
  :items-per-page="-1"
  hide-default-footer
  class="elevation-1"
>

问题2:显示表头排序指示器

自定义表头插槽时覆盖了默认排序指示器的结构,需要在插槽中手动保留或复用排序相关元素:

方式1:手动添加排序图标

以price列为例,修改表头插槽:

<template v-slot:column.price="{ header }">
  <div class="d-flex align-center">
    Price ({{wallets.rel.ticker }})
    <v-icon v-if="header.sortable" class="ml-1" size="small">
      {{ header.sort === 'asc' ? 'mdi-arrow-up' : header.sort === 'desc' ? 'mdi-arrow-down' : 'mdi-unfold-more' }}
    </v-icon>
  </div>
</template>

同时确保表头配置中对应列开启sortable: true:

// 示例headers配置
const asksHeaders = [
  { key: 'price', text: 'Price', sortable: true },
  { key: 'maxvolume', text: 'Amount', sortable: true },
  { key: 'relamount', text: 'Total', sortable: true }
]

方式2:复用默认表头结构

如果不想手动写图标,可通过header.render()渲染原表头内容,再追加自定义文本:

<template v-slot:column.price="{ header }">
  <div>
    {{ header.render() }}
    <span>({{wallets.rel.ticker }})</span>
  </div>
</template>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 18:42:08