web-dev-qa-db-ja.com

vuetifyのデータテーブルで「カスタムフィルター」プロップを使用するにはどうすればよいですか?または、ヘッダーでフィルタリングするカスタムフィルターを作成するにはどうすればよいですか?

投稿日現在、データテーブルで「カスタムフィルター」プロパティを使用するドキュメントは見つかりません。

ヘッダーでデータテーブルをフィルター処理するカスタムフィルターを作成したいだけです。ドロップダウンがあり、ユーザーがドロップダウンのオプションのいずれかをクリックすると、特定のヘッダーのリストがフィルターされます。

例:ドロップダウンオプション:食品の種類:果物、肉、野菜

  1. バクチョイ(野菜)
  2. 豚肉(肉)
  3. 鶏もも肉(肉)
  4. スイカ(果物)

ドロップダウンを肉として選択した場合、豚肉と鶏肉のみが表示されます。

14
alwayshungryleh

Githubのコード を見ると、customFilter propがfilter propがアイテムに適用される方法を決定するために使用されるデフォルトのメソッドを上書きするために使用されているように見えますテーブル。

デフォルトのcustomFilterメソッドは、各アイテムオブジェクトの各プロパティ名にfilter関数を適用し、フィルターを通過する1つのプロパティ名を含まないアイテムを除外します。

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

列がフィルターに含まれないようにしたい場合、またはフィルターで除外されないように常にしたい特定の行がある場合は、この関数を上書きできます。

メソッドはsearch propにも依存することに気付くでしょう。これは文字列でなければなりません。


とは言っても、やりたいことのためにそのプロップを使う必要はありません。ドロップダウン値に基づいてアイテムをフィルタリングする計算プロパティを作成し、その計算プロパティをitemsプロパティとして渡すだけです。

以下に例を示します。

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

このようにcustomFilterアプローチを使用することもできます。検索を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