Vuetify数据表内联过滤器

时间:2019-08-09 15:18:17

标签: datatable vuetify.js

请参阅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])
    }
  }
})

See it in Action on CodePen

1 个答案:

答案 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)
            }
          }
        ]
      }
    }
})

我造了一支笔vuetify 2 data table column sort filter