使用 Vue 隐藏垂直 v-data-table 中的未填充行
Hiding unfilled rows in vertical v-data-table with Vue
以下是演示我的问题的执行table代码。
模板:
<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>
脚本:
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%',
},
],
}
},
})
这是结果:
wide-screen
大屏幕看起来不错。但是当我有较小的屏幕时,它开始看起来像这样:
small-screen
问题:如何在较小的屏幕上隐藏table的空白部分(/当所有内容都变成一栏时)。
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>
以下是演示我的问题的执行table代码。
模板:
<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>
脚本:
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%',
},
],
}
},
})
这是结果: wide-screen
大屏幕看起来不错。但是当我有较小的屏幕时,它开始看起来像这样:
small-screen
问题:如何在较小的屏幕上隐藏table的空白部分(/当所有内容都变成一栏时)。
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 functiononResize
to calculate the width of the current window, and assign value to theisMobile
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 thev-data-table
to use our custom design as shown on demo. Different designs on the base ofisMobile
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>