请参阅this pretty Example by Dave Fontz on CodePen,以了解如何存档日期表内联过滤器以及如何自定义如何显示vuetify v-data-table的标题和tableData行。
这对我来说就像acharm,vuetify版本低于2。
但是自从升级到vuetify版本2以来,
<template slot="headers" slot-scope="props">
和
<template slot="items" slot-scope="props">
内部
<v-data-table>
似乎被忽略。
关于如何迁移Daves解决方案以与vuetify版本2兼容的任何建议?
非常感谢任何帮助或提示!
下面也是戴夫的完整代码。
HTML:
<div id="app">
<v-app id="inspire">
<v-data-table
v-model="selected"
:headers="headers"
:items="filteredDesserts"
:pagination.sync="pagination"
select-all
item-key="name"
class="elevation-1"
>
<template slot="headers" slot-scope="props">
<tr>
<th>
<v-checkbox
:input-value="props.all"
:indeterminate="props.indeterminate"
primary
hide-details
@click.native="toggleAll"
></v-checkbox>
</th>
<th
v-for="header in props.headers"
:key="header.text"
:class="['column sortable', pagination.descending ? 'desc' : 'asc', header.value === pagination.sortBy ? 'active' : '']"
@click="changeSort(header.value)"
>
<v-icon small>arrow_upward</v-icon>
{{ header.text }}
</th>
</tr>
<tr class="grey lighten-3">
<th>
<v-icon>filter_list</v-icon>
</th>
<th
v-for="header in props.headers"
:key="header.text"
>
<div v-if="filters.hasOwnProperty(header.value)">
<v-select flat hide-details small multiple clearable :items="columnValueList(header.value)" v-model="filters[header.value]">
</v-select>
</div>
</th>
</tr>
</template>
<template slot="items" slot-scope="props">
<tr :active="props.selected" @click="props.selected = !props.selected">
<td>
<v-checkbox
:input-value="props.selected"
primary
hide-details
></v-checkbox>
</td>
<td>{{ props.item.name }}</td>
<td class="text-xs-right">{{ props.item.calories }}</td>
<td class="text-xs-right">{{ props.item.fat }}</td>
<td class="text-xs-right">{{ props.item.carbs }}</td>
<td class="text-xs-right">{{ props.item.protein }}</td>
<td class="text-xs-right">{{ props.item.iron }}</td>
</tr>
</template>
</v-data-table>
</v-app>
</div>
JS:
new Vue({
el: '#app',
data: () => ({
pagination: {
sortBy: 'name'
},
selected: [],
headers: [
{
text: 'Dessert (100g serving)',
align: 'left',
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' }
],
filters: {
fat: [],
carbs: [],
iron: [],
},
desserts: [
{
value: false,
name: 'Frozen Yogurt',
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
iron: '1%'
},
{
value: false,
name: 'Ice cream sandwich',
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
iron: '1%'
},
{
value: false,
name: 'Eclair',
calories: 262,
fat: 16.0,
carbs: 23,
protein: 6.0,
iron: '7%'
},
{
value: false,
name: 'Cupcake',
calories: 305,
fat: 3.7,
carbs: 67,
protein: 4.3,
iron: '8%'
},
{
value: false,
name: 'Gingerbread',
calories: 356,
fat: 16.0,
carbs: 49,
protein: 3.9,
iron: '16%'
},
{
value: false,
name: 'Jelly bean',
calories: 375,
fat: 0.0,
carbs: 94,
protein: 0.0,
iron: '0%'
},
{
value: false,
name: 'Lollipop',
calories: 392,
fat: 0.2,
carbs: 98,
protein: 0,
iron: '2%'
},
{
value: false,
name: 'Honeycomb',
calories: 408,
fat: 3.2,
carbs: 87,
protein: 6.5,
iron: '45%'
},
{
value: false,
name: 'Donut',
calories: 452,
fat: 25.0,
carbs: 51,
protein: 4.9,
iron: '22%'
},
{
value: false,
name: 'KitKat',
calories: 518,
fat: 26.0,
carbs: 65,
protein: 7,
iron: '6%'
}
]
}),
computed: {
filteredDesserts() {
return this.desserts.filter(d => {
return Object.keys(this.filters).every(f => {
return this.filters[f].length < 1 || this.filters[f].includes(d[f])
})
})
}
},
methods: {
toggleAll () {
if (this.selected.length) this.selected = []
else this.selected = this.desserts.slice()
},
changeSort (column) {
if (this.pagination.sortBy === column) {
this.pagination.descending = !this.pagination.descending
} else {
this.pagination.sortBy = column
this.pagination.descending = false
}
},
columnValueList(val) {
return this.desserts.map(d => d[val])
}
}
})
答案 0 :(得分:0)
我制作了一支可以过滤列的笔,它并不是您所要的,但它可能会给您一个想法。它使用来自vuetify 2文档的自定义过滤
HTML:
<div id="app">
<v-app id="inspire">
<template>
<div>
<v-data-table
dense
:headers="headers"
:items="desserts"
item-key="name"
class="elevation-1"
:search="search"
>
<template v-slot:body.prepend>
<tr>
<td>
<v-text-field v-model="search" type="text" label="Dessert name"></v-text-field>
</td>
<td>
<v-text-field v-model="calories" type="number" label="Less than"></v-text-field>
</td>
<td>
<v-text-field v-model="fat" type="number" label="Less than"></v-text-field>
</td>
<td>
<v-text-field v-model="carbs" type="number" label="Less than"></v-text-field>
</td>
</tr>
</template>
</v-data-table>
</div>
</template>
</v-app>
</div>
和JS:
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return {
search: '',
name: '',
calories: '',
fat:'',
carbs:'',
desserts: [
{
name: 'Frozen Yogurt',
calories: 159,
fat: 6.0,
carbs: 24
},
{
name: 'Ice cream sandwich',
calories: 237,
fat: 9.0,
carbs: 37,
},
{
name: 'Eclair',
calories: 262,
fat: 16.0,
carbs: 23,
},
{
name: 'Cupcake',
calories: 305,
fat: 3.7,
carbs: 67,
},
{
name: 'Gingerbread',
calories: 356,
fat: 16.0,
carbs: 49,
},
{
name: 'Jelly bean',
calories: 375,
fat: 0.0,
carbs: 94,
},
{
name: 'Lollipop',
calories: 392,
fat: 0.2,
carbs: 98,
},
{
name: 'Honeycomb',
calories: 408,
fat: 3.2,
carbs: 87,
},
{
name: 'Donut',
calories: 452,
fat: 25.0,
carbs: 51,
},
{
name: 'KitKat',
calories: 518,
fat: 26.0,
carbs: 65,
},
],
}
},
computed: {
headers () {
return [
{
text: 'Dessert (100g serving)',
align: 'left',
sortable: false,
value: 'name',
filter: value => {
if (!this.name) return true
return value < value
}
},
{
text: 'Calories',
value: 'calories',
filter: value => {
if (!this.calories) return true
return value < parseInt(this.calories)
}
},
{ text: 'Fat (g)', value: 'fat',filter: value => {
if (!this.fat) return true
return value < parseInt(this.fat)
}, },
{ text: 'Carbs (g)', value: 'carbs',
filter: value => {
if (!this.carbs) return true
return value < parseInt(this.carbs)
}
}
]
}
}
})