Vuetify:如何过滤 v-data-table 中的数据?

Posted

技术标签:

【中文标题】Vuetify:如何过滤 v-data-table 中的数据?【英文标题】:Vuetify: How to filter data in v-data-table? 【发布时间】:2018-12-11 21:34:48 【问题描述】:

在数据表中,我只想显示属性“display”为“true”的项目。组件v-data-table 中有属性“过滤器”。但是没有示例显示,如何使用它。

我尝试了几种方法,但都没有成功。以下代码 sn-p 也可在codepen 获得。

new Vue(
  el: '#app',
  data () 
    return 
      headers: [
        
          text: 'Dessert (100g serving)',
          align: 'left',
          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: [
        
          value: false,
          name: 'Frozen Yogurt',
          calories: 159,
          fat: 6.0,
          carbs: 24,
          protein: 4.0,
          iron: '1%',
          display: false
        ,
        
          value: false,
          name: 'Ice cream sandwich',
          calories: 237,
          fat: 9.0,
          carbs: 37,
          protein: 4.3,
          iron: '1%',
          display: true
        ,
        
          value: false,
          name: 'Eclair',
          calories: 262,
          fat: 16.0,
          carbs: 23,
          protein: 6.0,
          iron: '7%',
          display: false
        ,
        
          value: false,
          name: 'Cupcake',
          calories: 305,
          fat: 3.7,
          carbs: 67,
          protein: 4.3,
          iron: '8%',
          display: true
        ,
        
          value: false,
          name: 'Gingerbread',
          calories: 356,
          fat: 16.0,
          carbs: 49,
          protein: 3.9,
          iron: '16%',
          display: false
        ,
        
          value: false,
          name: 'Jelly bean',
          calories: 375,
          fat: 0.0,
          carbs: 94,
          protein: 0.0,
          iron: '0%',
          display: true
        ,
        
          value: false,
          name: 'Lollipop',
          calories: 392,
          fat: 0.2,
          carbs: 98,
          protein: 0,
          iron: '2%',
          display: false
        ,
        
          value: false,
          name: 'Honeycomb',
          calories: 408,
          fat: 3.2,
          carbs: 87,
          protein: 6.5,
          iron: '45%',
          display: false
        ,
        
          value: false,
          name: 'Donut',
          calories: 452,
          fat: 25.0,
          carbs: 51,
          protein: 4.9,
          iron: '22%',
          display: false
        ,
        
          value: false,
          name: 'KitKat',
          calories: 518,
          fat: 26.0,
          carbs: 65,
          protein: 7,
          iron: '6%',
          display: false
        
      ]
    
  ,
  methods: 
    filterItems(val, search) 
      return val.display;
    
  
)
<!DOCTYPE html>
<html>
<head>
  <link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet">
  <link href="https://unpkg.com/vuetify/dist/vuetify.min.css" rel="stylesheet">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<body>

<div id="app">
  <v-app id="inspire">
    <v-data-table
      :headers="headers"
      :items="desserts"
      hide-actions
      item-key="name"
      :filter="filterItems"
    >
      <template slot="items" slot-scope="props">
        <tr @click="props.expanded = !props.expanded" :class="[props.expanded && 'expanded']">
          <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>
      <template slot="expand" slot-scope="props">
        <v-card flat>
          <v-card-text>Peek-a-boo!</v-card-text>
        </v-card>
      </template>
    </v-data-table>
  </v-app>
</div>

  <script src="https://unpkg.com/vue/dist/vue.js"></script>
  <script src="https://unpkg.com/vuetify/dist/vuetify.js"></script>
</body>
</html>

代码有问题的部分是:

  methods: 
    filterItems(val, search) 
      return ???;
    
  

【问题讨论】:

【参考方案1】:

我在这个问题上苦苦挣扎了很长时间,因为我还认为 :filter 不起作用。后来,经过一番痛苦,我意识到我需要一个 :search 道具来使用 :filter,而我想要的功能并不是 Vuetify 提供的功能。

和你一样,我想用一个返回布尔值的函数过滤我的数据表,即:如果应该显示行,则为 true。

如果有人正在寻找一个快速的解决方案来做同样的事情,一个简单的“v-if”应该可以解决问题。根据上面的例子:

<template slot="items" slot-scope="props" v-if="props.item.display">

当然还有其他解决方案,这取决于您的需要,例如在甜点数组本身上使用 .filter 方法。

在我的例子中,因为我想总是在我的数据表中一次显示 5 行(不使用隐藏操作),所以我最终使用 created() 生命周期挂钩,而不是 v-if:

created: function() 
this.shownDesserts = this.desserts.filter(dessert => 
  return dessert.display
)

,

【讨论】:

【参考方案2】:

Looking at the source code,我想你真的想要custom-filter 而不是filter

(items: object[], search: string, filter: Filter): object[]

因此,您将定义一个函数并将其作为参数传递给表上的custom-filter 属性。搜索时,您会看到由对象数组 (object[]) 表示的表中的所有项目、在搜索框中键入的搜索字符串以及应用于数组中所有对象的过滤函数,所以:

:custom-filter="filterItems"

filterItems(items, search, filter) 
    items.filter(r => filter(r.calories > search))

以上当然只是一个非常初级的例子。

【讨论】:

过滤器 (:filter, :custom-filter) 似乎不起作用。我简单地尝试了:'filterItems(items, search, filter) console.log(items); ',但控制台保持为空。见:codepen.io/antoninslejska/pen/qKwBda?editors=1011 KaelWD 在问题中写道: customFilter 仅在您使用 search 道具时被调用,并且它作为第三个参数传递过滤器。 API 有点混乱且难以使用,但正在为将来的版本进行改进。 @ScottBaker 您使用的是 vuetify 2 还是 vuetify 1.5?他们稍微改变了他们的 monorepo。【参考方案3】:

这是我想出的解决方案。我遇到了类似的问题,我想实现一个仍然适用于搜索的自定义过滤器。我最终使用了一个计算属性,该属性将过滤器应用于数据,并且该计算属性是发送到表的内容。

computed: 
  dataListDisplay: function() 
    return this.applyFilters(this.dataList);
  ,

dataListDisplay 是您发送到 v-data-table items 道具的内容。您需要按照自己的意愿实现 applFilters 函数。

我的表是只读的。我想如果您要更改数据,则必须小心。您可能需要为 dataListDisplay 计算函数提供一个设置器。

【讨论】:

【参考方案4】:

对于道具,过滤器,这应该会有所帮助:

methods: 
  filterItems(val, search) 
    return val != null && typeof val !== 'boolean' && val.toString().toLowerCase().indexOf(search) !== -1;
  

【讨论】:

以上是关于Vuetify:如何过滤 v-data-table 中的数据?的主要内容,如果未能解决你的问题,请参考以下文章

Vue, Vuetify 2, v-data-table - 如何在表格底部显示总原始数据

如何在 v-data-table Vue.js + Vuetify 中显示和隐藏行

如何在 Vuetify v-data-table 上对齐标题

Vuetify v-data-table 拖放

在 vuetify 中为 v-data-table 的第一行添加样式

Vuetify - 在 v-data-table 上包装标题文本