過去より未来に近い今

30オーバーでも始めるには今より遅いことはない。育児と技術両方諦めないようにアウトプット。

VuetifyのData tablesのpaddingはclassで指定できる

VuetifyのData tablesは癖があって、幅調整等が結構ややこしいのですが、paddingを調整することで意図した幅調整ができる可能性があります。

VuetifyのData tablesの幅(width)調整は分かりづらい

公式ドキュメントを見てプロパティや例を見ても、幅調整についてはあまり書かれていません。ところが意外にSPAで作ろうとしたときに横軸のスクロールがあるのが気に食わないことがあります。

v15.vuetifyjs.com

一応以下のようにwidthのpropsで%または数字(px)などで指定すると調整が可能ということなのですが、tableの項目名が同じ長さではなく、かつレスポンシブにしている場合にこの%指定は必ずしも望む指定方法になりません。

<script>
  export default {
    data () {
      return {
        headers: [
          {text: 'Dessert (100g serving)', value: 'name', width: '16%' },
          { text: 'Calories', value: 'calories', width: '16%' },
          { text: 'Fat (g)', value: 'fat', width: '16%' },
          { text: 'Carbs (g)', value: 'carbs', width: '16%' },
          { text: 'Protein (g)', value: 'protein', width: '16%' },
          { text: 'Iron (%)', value: 'iron', width: '16%' }
        ],
        desserts: [
          {
            name: 'Frozen Yogurt',
            calories: 159,
            fat: 6.0,
            carbs: 24,
            protein: 4.0,
            iron: '1%'
          },
          {
            name: 'Ice cream sandwich',
            calories: 237,
            fat: 9.0,
            carbs: 37,
            protein: 4.3,
            iron: '1%'
          },
          {
            name: 'Eclair',
            calories: 262,
            fat: 16.0,
            carbs: 23,
            protein: 6.0,
            iron: '7%'
          },
          {
            name: 'Cupcake',
            calories: 305,
            fat: 3.7,
            carbs: 67,
            protein: 4.3,
            iron: '8%'
          },
          {
            name: 'Gingerbread',
            calories: 356,
            fat: 16.0,
            carbs: 49,
            protein: 3.9,
            iron: '16%'
          },
          {
            name: 'Jelly bean',
            calories: 375,
            fat: 0.0,
            carbs: 94,
            protein: 0.0,
            iron: '0%'
          },
          {
            name: 'Lollipop',
            calories: 392,
            fat: 0.2,
            carbs: 98,
            protein: 0,
            iron: '2%'
          },
          {
            name: 'Honeycomb',
            calories: 408,
            fat: 3.2,
            carbs: 87,
            protein: 6.5,
            iron: '45%'
          },
          {
            name: 'Donut',
            calories: 452,
            fat: 25.0,
            carbs: 51,
            protein: 4.9,
            iron: '22%'
          },
          {
            name: 'KitKat',
            calories: 518,
            fat: 26.0,
            carbs: 65,
            protein: 7,
            iron: '6%'
          }
        ]
      }
    }
  }
</script>

ChromeのDevToolで見てみよう

data tablesがどのような作りになっているのか、どんな定義がされているのかをDev toolで見てみましょう。

Dev toolはChromeの場合、右の方にある縦3つの点々のメニュー(クリリンの頭の半分みたいなマーク)>その他のツール>デベロッパーツールで開くか、F12で開けます。 そのDev Toolの左上に以下のマークがあるのでこれをクリック。

そうするとブラウザ上の要素の情報が見れるようになります。 これでdata tablesを見てみるとpaddingが結構取られていることがわかりました。 このpaddingを調整して、幅を絞れないか試行錯誤した結果、他のコンポーネント指定と同様にclassで指定すれば解決しました。

Chrome dev tool
Chrome dev tool

data tablesのpaddingを指定してみる

先程の例でやってみます。 以下のようにclass propsでVuetifyのclass内のpadding定義を記載するとその定義内容が反映され、paddingの操作が可能です。

<script>
  export default {
    data () {
      return {
        headers: [
          {text: 'Dessert (100g serving)', value: 'name', class: 'px-0' },
          { text: 'Calories', value: 'calories', class: 'px-0' },
          { text: 'Fat (g)', value: 'fat', class: 'px-0' },
          { text: 'Carbs (g)', value: 'carbs', class: 'px-0' },
          { text: 'Protein (g)', value: 'protein', class: 'px-0' },
          { text: 'Iron (%)', value: 'iron', class: 'px-0' }
        ],
        desserts: [
          {
            name: 'Frozen Yogurt',
            calories: 159,
            fat: 6.0,
            carbs: 24,
            protein: 4.0,
            iron: '1%'
          },
          {
            name: 'Ice cream sandwich',
            calories: 237,
            fat: 9.0,
            carbs: 37,
            protein: 4.3,
            iron: '1%'
          },
          {
            name: 'Eclair',
            calories: 262,
            fat: 16.0,
            carbs: 23,
            protein: 6.0,
            iron: '7%'
          },
          {
            name: 'Cupcake',
            calories: 305,
            fat: 3.7,
            carbs: 67,
            protein: 4.3,
            iron: '8%'
          },
          {
            name: 'Gingerbread',
            calories: 356,
            fat: 16.0,
            carbs: 49,
            protein: 3.9,
            iron: '16%'
          },
          {
            name: 'Jelly bean',
            calories: 375,
            fat: 0.0,
            carbs: 94,
            protein: 0.0,
            iron: '0%'
          },
          {
            name: 'Lollipop',
            calories: 392,
            fat: 0.2,
            carbs: 98,
            protein: 0,
            iron: '2%'
          },
          {
            name: 'Honeycomb',
            calories: 408,
            fat: 3.2,
            carbs: 87,
            protein: 6.5,
            iron: '45%'
          },
          {
            name: 'Donut',
            calories: 452,
            fat: 25.0,
            carbs: 51,
            protein: 4.9,
            iron: '22%'
          },
          {
            name: 'KitKat',
            calories: 518,
            fat: 26.0,
            carbs: 65,
            protein: 7,
            iron: '6%'
          }
        ]
      }
    }
  }
</script>

以下は実際のサンプルとして一部上記と同様の変更を行った場合となります。 paddingが変更されていることがわかります。

data部分も同様です。ver1.5あたりだとデータ部分の指定が必要なので、以下のような例となります。 ここでclassに同じように追加するとdata部分についてもpaddingの調整が可能です。

<template>
  <v-data-table
    :headers="headers"
    :items="desserts"
    class="elevation-1"
  >
    <template v-slot:items="props">
      <td>{{ props.item.name }}</td>
      <td class="text-xs-right pa-0">{{ props.item.calories }}</td>
      <td class="text-xs-right pa-0">{{ props.item.fat }}</td>
      <td class="text-xs-right pa-0">{{ props.item.carbs }}</td>
      <td class="text-xs-right pa-0">{{ props.item.protein }}</td>
      <td class="text-xs-right pa-0">{{ props.item.iron }}</td>
    </template>
  </v-data-table>
</template>

こちらも実際にやってみると以下のように反映されていることがわかります。

data tablesとうまく向き合う

Vuetifyのdata tablesはうまく利用するととても簡単にsort可能で、パージネイションも実装、選択行の抽出も簡単なので、うまく使っていければ有用なコンポーネントです。 公式ドキュメントを見ても分かりづらいため、トライ&エラーでやるしかありませんでしたが、やってみるとVuetifyの標準的なスタイル定義が変わらずでした。