Home > Blockchain >  Change vuetify simple-table to data-table
Change vuetify simple-table to data-table

Time:03-26

I have this simple table in Vuetify, without headers and only one column. How can I change it to vuetify v-data-table?

  <v-simple-table>
    <thead />
    <tbody>
      <tr
        v-for="item in categories"
        :key="item"
        @click="handleClick"
      >
        <td>{{ item }}</td>
        <v-switch />
      </tr>
    </tbody>
  </v-simple-table>

categories is a simple array of strings. I want to change it to data-table in order to nicely handle clicking and selecting rows.

CodePudding user response:

You can change like this :

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data: () => ({
    categoryList: ['Category 1', 'Category 2', 'Category 3'],
  }),
  computed: {
    categoriesHeader() {
      return [
        { text: "Name", value: "name" }
      ];
    },
  },
})
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/vuetify/dist/vuetify.min.css" rel="stylesheet">
<div id="app">
  <v-app id="a">
    <v-data-table :headers="categoriesHeader" :items="categoryList" item-key="id" >
      <template v-slot:[`item.name`]="{ item }">
        {{ item }}
      </template>
    </v-data-table>
  </v-app>
</div>

CodePudding user response:

Check this codesandbox I made: https://codesandbox.io/s/stack-71617004-simple-to-v-data-table-bm2yn1?file=/src/components/Example.vue

Using body slot

You can use the body slot of the data table and use almost the same code you have in your simple table like this. This way you set up the handleClick function in the tr:

<v-data-table
   :headers="headers"
   :items="items"
   hide-default-footer
   hide-default-header               
   :items-per-page="-1"
   :footer-props="{
      itemsPerPageOptions: [-1],
   }"
>
   <template v-slot:body="{ items}">
      <tbody>
         <tr v-for="item in items" :key="item"  @click="handleClick(item)">
               <td align="left">{{item}}</td>
         </tr>
      </tbody>
   </template>
</v-data-table>

Using item slot

Or you can use the item slot, like this. In this other way, the handleClick function is configured using the @click:row event of the data table.

If you try to use the item slot with your array of strings, it will work but you'll get some warnings in your console. Telling you that your data-table item slot expected an object and received an string. That's because v-data-table component expects to receive an array of objects.

To avoid this warning you can simply convert your array of string into a dummy array of objects using Array.prototype.map, and bind the computed property instead.

computed: {
   myItemsTransformed() {
      return this.items.map(item => ({ name: item }));
   }
},
<v-data-table
   :headers="headers"
   :items="myItemsTransformed"
   hide-default-footer
   hide-default-header               
   :items-per-page="-1"
   :footer-props="{
      itemsPerPageOptions: [-1],
   }"               
   @click:row="(item) => handleClick(item.name)"
>
   <template #item.name="{ item }">
      {{ item.name }}
   </template>
</v-data-table>

Notice that in both examples I have used the props hide-default-footer, hide-default-header to hide the footer and header of the data table and also set the items-per-page to -1. To show all the items of the table and avoid the pagination.

  • Related