2022年10月12日水曜日

QuasarでQTableのexpandを使う方法

QuasarでQTableのexpandを使う方法

概要

特定のカラムの情報だけexpandで表示したい場合などに使えます
expand 後に更にテーブルを使う方法も紹介します

環境

  • macOS 11.7
  • node 18.9.0
  • quasar 2.8.2

サンプルコード

  • vim src/pages/IndexPage.vue
<template>
  <div class="q-pa-md">
    <q-table
      title="Treats"
      :rows="rows"
      :columns="columns"
      row-key="name"
    >

      <template v-slot:header="props">
        <q-tr :props="props">
          <q-th auto-width />
          <q-th
            v-for="col in props.cols"
            :key="col.name"
            :props="props"
          >
            {{ col.label }}
          </q-th>
        </q-tr>
      </template>

      <template v-slot:body="props">
        <q-tr :props="props">
          <q-td auto-width>
            <q-btn size="sm" color="accent" round dense @click="props.expand = !props.expand" :icon="props.expand ? 'remove' : 'add'" />
          </q-td>
          <q-td
            v-for="col in props.cols"
            :key="col.name"
            :props="props"
          >
            {{ col.value }}
          </q-td>
        </q-tr>
        <q-tr v-show="props.expand">
          <q-td
            colspan="100%"
            v-for="favorite in props.row.favorites"
            :key="favorite.id"
          >
            <q-chip color="primary" text-color="white" icon="edit">
              {{ favorite.color }}
            </q-chip>
            <q-chip color="red" text-color="white" icon="sports">
              {{ favorite.sports }}
            </q-chip>
            <q-chip color="green" text-color="white" icon="restaurant">
              {{ favorite.food}}
            </q-chip>
          </q-td>
        </q-tr>
      </template>

    </q-table>
  </div>
</template>

<script setup lang="ts">
const columns = [
  { name: 'name', required: true, label: 'name', align: 'left', field: 'name', sortable: true },
  { name: 'age', label: 'age', field: 'age', sortable: true },
]

const rows = [
  {
    id: 1,
    name: 'hawk',
    age: 10,
    favorites: [{'color': 'blue', 'sports': 'soccer', 'food': 'bread'}],
  },
  {
    id: 2,
    name: 'snowlog',
    age: 20,
    favorites: [{'color': 'red', 'sports': 'basketball', 'food': 'rice'}],
  },
  {
    id:3,
    name: 'taro',
    age: 30,
    favorites: [{'color': 'green', 'sports': 'tennis', 'food': 'meat'}],
  },
]
</script>

expand 後の更にQTableを使う方法

<template>
  <div class="q-pa-md">
    <q-table
      title="Treats"
      :rows="rows"
      :columns="columns"
      row-key="name"
    >

      <template v-slot:header="props">
        <q-tr :props="props">
          <q-th auto-width />
          <q-th
            v-for="col in props.cols"
            :key="col.name"
            :props="props"
          >
            {{ col.label }}
          </q-th>
        </q-tr>
      </template>

      <template v-slot:body="props">
        <q-tr :props="props">
          <q-td auto-width>
            <q-btn size="sm" color="accent" round dense @click="props.expand = !props.expand" :icon="props.expand ? 'remove' : 'add'" />
          </q-td>
          <q-td
            v-for="col in props.cols"
            :key="col.name"
            :props="props"
          >
            {{ col.value }}
          </q-td>
        </q-tr>
        <q-tr v-show="props.expand">
          <q-td
            colspan="100%"
          >
            <q-table
              title="Favorites"
              :rows="props.row.favorites"
              :columns="nextedColumns"
              row-key="id"
              flat
            >
            </q-table>
          </q-td>
        </q-tr>
      </template>

    </q-table>
  </div>
</template>

<script setup lang="ts">
const columns = [
  { name: 'name', required: true, label: 'name', align: 'left', field: 'name', sortable: true },
  { name: 'age', label: 'age', field: 'age', sortable: true },
]

const nextedColums = [
  { name: 'color', label: 'color', field: 'color' },
  { name: 'sports', label: 'sports', field: 'sports' },
  { name: 'food', label: 'food', field: 'food' },
]

const rows = [
  {
    id: 1,
    name: 'hawk',
    age: 10,
    favorites: [{'color': 'blue', 'sports': 'soccer', 'food': 'bread'}],
  },
  {
    id: 2,
    name: 'snowlog',
    age: 20,
    favorites: [{'color': 'red', 'sports': 'basketball', 'food': 'rice'}],
  },
  {
    id:3,
    name: 'taro',
    age: 30,
    favorites: [{'color': 'green', 'sports': 'tennis', 'food': 'meat'}],
  },
]
</script>

ちょっと解説

ポイントは入れ子にするオブジェクト専用のカラム情報を作成する点です
あとは値を渡すときに props.row.favarites という感じでexpandした際にだけ表示するカラムをループで渡してあげればOKです

また flat 属性を指定してあげるとテーブルが入れ子になってもキレイに表示されるのでおすすめです

0 件のコメント:

コメントを投稿