web-dev-qa-db-fra.com

Comment utiliser l'accessoire "filtre personnalisé" dans les tableaux de données dans vuetify? ou Comment créer un filtre personnalisé pour filtrer par en-têtes?

À la date de publication, je ne trouve aucune documentation pour utiliser l'accessoire "filtre personnalisé" dans les tableaux de données.

Je veux juste créer un filtre personnalisé pour filtrer ma table de données par en-têtes. J'ai une liste déroulante et lorsque l'utilisateur clique sur l'une des options de la liste déroulante, il filtrera la liste pour un en-tête spécifique.

Exemple: Options déroulantes: Type d'aliment: fruits, viande, légumes

  1. Bakchoi (légume)
  2. La viande de porc)
  3. Cuisse de poulet (viande)
  4. pastèque (fruit)

Si je sélectionne le menu déroulant comme viande, il ne devrait me montrer que la cuisse de porc et de poulet.

14
alwayshungryleh

En regardant le code sur Github , il semble que le prop customFilter est utilisé pour écraser la méthode par défaut utilisée pour déterminer comment le prop filter est appliqué aux éléments dans la table.

La méthode customFilter par défaut applique la fonction filter à chaque nom de propriété de chaque objet élément et filtre tous les éléments qui n'incluent pas un nom de propriété qui passe le filtre:

customFilter: {
  type: Function,
  default: (items, search, filter) => {
    search = search.toString().toLowerCase()
    return items.filter(i => (
      Object.keys(i).some(j => filter(i[j], search))
    ))
  }
},

Vous souhaiterez peut-être remplacer cette fonction si vous souhaitez empêcher l'inclusion de colonnes dans le filtre ou s'il existe des lignes spécifiques que vous souhaitez toujours empêcher de filtrer.

Vous remarquerez que la méthode dépend également de la propriété search, qui doit être une chaîne.


Cela dit, vous n'avez vraiment pas besoin d'utiliser cet accessoire pour ce que vous voulez faire. Vous devez simplement créer une propriété calculée pour filtrer les éléments en fonction de votre valeur déroulante et transmettre cette propriété calculée en tant que prop items.

Voici un exemple:

new Vue({
  el: '#app',
  data() {
    return {
      food: [
        { name: 'Bakchoi', type: 'vegetable', calories: 100 },
        { name: 'Pork', type: 'meat', calories: 200 },
        { name: 'Chicken Thigh', type: 'meat', calories: 300 },
        { name: 'Watermelon', type: 'fruit', calories: 10 },
      ],
      headers: [
        { text: 'Name', align: 'left', value: 'name' },
        { text: 'Food Type', align: 'left', value: 'type' }, 
        { text: 'Calories', align: 'left', value: 'calories' },
      ],
      foodType: null,
    };
  },
  computed: {
    filteredItems() {
      return this.food.filter((i) => {
        return !this.foodType || (i.type === this.foodType);
      })
    }
  }
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuetify.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/vuetify.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons">

<div id="app">
  <v-app>  
    <v-select 
      label="Food Type" 
      :items="['vegetable', 'meat', 'fruit']"
      v-model="foodType"
    ></v-select>
    
    <v-data-table 
      :headers="headers"
      :items="filteredItems"
      hide-actions
    >
      <template slot="items" scope="{ item }">
        <td>{{ item.name }}</td>
        <td>{{ item.type }}</td>
        <td>{{ item.calories }}</td>
      </template>
    </v-data-table>
  </v-app>
</div>
21
thanksd

Vous pouvez également utiliser l'approche customFilter comme ceci, j'ai limité la recherche au champ type.

new Vue({
    el: '#app',
    data() {
        return {
            food: [
                { name: 'Bakchoi', type: 'vegetable', calories: 100 },
                { name: 'Pork', type: 'meat', calories: 200 },
                { name: 'Chicken Thigh', type: 'meat', calories: 300 },
                { name: 'Watermelon', type: 'fruit', calories: 10 },
            ],
            headers: [
                { text: 'Name', align: 'left', value: 'name' },
                { text: 'Food Type', align: 'left', value: 'type' },
                { text: 'Calories', align: 'left', value: 'calories' },
            ],
            search: '',

        };
    },
    methods: {
        customFilter(items, search, filter) {

            search = search.toString().toLowerCase()
            return items.filter(row => filter(row["type"], search));

        }
    }
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuetify.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/vuetify.min.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons">

<div id="app">
    <v-app>
        <v-select
                label="Food Type"
                :items="['vegetable', 'meat', 'fruit']"
                v-model="search"
        ></v-select>

        <v-data-table
                :headers="headers"
                :items="food"
                :search="search"
                :custom-filter="customFilter"
                hide-actions
        >
            <template slot="items" scope="{ item }">
                <td>{{ item.name }}</td>
                <td>{{ item.type }}</td>
                <td>{{ item.calories }}</td>
            </template>
        </v-data-table>
    </v-app>
</div>
9
Soth