1

Following is executable code to demonstrate my problem.

Template:

<div id="app">
  <v-app id="inspire">
    <v-data-table
      :headers="headers"
      :items="desserts"
      hide-default-header
      hide-default-footer
      class="elevation-1"
    ></v-data-table>
  </v-app>
</div>

Script:

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data () {
    return {
      headers: [
        {
          text: 'Dessert (100g serving)',
          align: 'start',
          value: 'name',
        },
        { text: 'Calories', value: 'calories' },
        { text: 'Fat (g)', value: 'fat' },
        { text: 'Carbs (g)', value: 'carbs' },
        { text: 'Protein (g)', value: 'protein' },
        { text: 'Iron (%)', value: 'iron' },
      ],
      desserts: [
        {
          name: 'Frozen Yogurt',
          calories: 159,
          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,
          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,
          iron: '45%',
        },
        {
          name: 'Donut',
          calories: 452,
          fat: 25.0,
          carbs: 51,
          protein: 4.9,
          iron: '22%',
        },
        {
          name: 'KitKat',
          carbs: 65,
          protein: 7,
          iron: '6%',
        },
      ],
    }
  },
})

This is the result: wide-screen

Looks all right with larger screens. But when I do have smaller screens, it starts to look like this:

small-screen

Question: how do I hide the empty parts of the table at smaller screens(/when everything just becomes one column).

  • Not OK if we put 0 if doesn't have value? – Arslan Butt Dec 30 '21 at 17:17
  • Hmm, that would be a solution, but sadly not a good solution for the project I am working on. But thanks for the suggestion! –  Dec 30 '21 at 19:08
  • well, it depends on your requirement, the solutions I provide are based on your current requirement as in the question. Don't forget to vote for my answer :) Thanks – Arslan Butt Dec 30 '21 at 19:13

1 Answers1

0

You can assign prop value in v-data-table mobile-breakpoint="0", so now you can add your custom functionality on your desired screen size. On windows resize I'm calling the function onResize to calculate the width of the current window, and assign value to the isMobile variable to true if the window width is less than 769 (you can change this value), now we will add <template v-slot:item="{ item }"> in the v-data-table to use our custom design as shown on demo. Different designs on the base of isMobile value.

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
 data: () => ({
   isMobile: false,
       windowSize: {
        x: 0,
        y: 0,
      },
       headers: [
        {
          text: 'Dessert (100g serving)',
          align: 'start',
          sortable: false,
          value: 'name',
        },
        { text: 'Calories', value: 'calories' },
        { text: 'Fat (g)', value: 'fat' },
        { text: 'Carbs (g)', value: 'carbs' },
        { text: 'Protein (g)', value: 'protein' },
        { text: 'Iron (%)', value: 'iron' },
      ],
       desserts: [
        {
          name: 'Frozen Yogurt',
          calories: 159,
          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,
          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,
          iron: '45%',
        },
        {
          name: 'Donut',
          calories: 452,
          fat: 25.0,
          carbs: 51,
          protein: 4.9,
          iron: '22%',
        },
        {
          name: 'KitKat',
          carbs: 65,
          protein: 7,
          iron: '6%',
        },
      ],
  
  }),
  mounted() {
    this.onResize();
  },

  methods: {
       onResize() {
      this.windowSize = { x: window.innerWidth, y: window.innerHeight };

        if (this.windowSize.x < 769) {
         this.isMobile = true; 
        } else{
           this.isMobile = false;
          }
      }
  },
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.24.0/axios.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>


 <div id="app">
  <v-app id="inspire">
   <div v-resize="onResize" class="pt-20">
    <v-data-table
      :headers="headers"
      :items="desserts"
      :items-per-page="5"
      class="elevation-1"
      hide-default-header
      hide-default-footer
      mobile-breakpoint="0"          
    >
       <template v-slot:item="{ item }">
                <tr v-if="isMobile == false">
                  <td>{{ item.name }} not mobile view</td>
                  <td class="text-xs-right">{{ item.calories }}</td>
                  <td class="text-xs-right">{{item.fat }}</td>
                  <td class="text-xs-right">{{ item.carbs }}</td>
                  <td class="text-xs-right">{{ item.protein }}</td>
                  <td class="text-xs-right">{{ item.iron }}</td>
                </tr>
                <tr v-else>
                  <td>
                    <v-list-item-group>
          <v-list-item v-if="item.name  != undefined">
            <v-list-item-content>
              <v-list-item-title v-text="item.name "></v-list-item-title>
            </v-list-item-content>
          </v-list-item>
          
           <v-list-item v-if="item.calories  != undefined">
            <v-list-item-content>
              <v-list-item-title v-text="item.calories "></v-list-item-title>
            </v-list-item-content>
          </v-list-item>
          
            <v-list-item v-if="item.fat  != undefined">
            <v-list-item-content>
              <v-list-item-title v-text="item.fat "></v-list-item-title>
            </v-list-item-content>
          </v-list-item>
          
           <v-list-item v-if="item.carbs  != undefined">
            <v-list-item-content>
              <v-list-item-title v-text="item.carbs "></v-list-item-title>
            </v-list-item-content>
          </v-list-item>
          
            <v-list-item v-if="item.protein  != undefined">
            <v-list-item-content>
              <v-list-item-title v-text="item.protein "></v-list-item-title>
            </v-list-item-content>
          </v-list-item>
          
           <v-list-item v-if="item.iron  != undefined">
            <v-list-item-content>
              <v-list-item-title v-text="item.iron "></v-list-item-title>
            </v-list-item-content>
          </v-list-item>
          
          
        </v-list-item-group>
                  </td>
                </tr>
              </template>
    </v-data-table>
             </div>
    </v-app>
</div>
Arslan Butt
  • 775
  • 1
  • 8
  • 20