【问题标题】:Quasar table column filteringQuasar 表列过滤
【发布时间】:2026-02-22 13:00:02
【问题描述】:

1) 有没有办法实现类似于数据表的类星体表列过滤? https://datatables.net/extensions/fixedheader/examples/options/columnFiltering.html

理想情况下,它将是一个自动填充文本字段,它会过滤表格上的所有行。我有一个有 25 列的表,所以想要一些健壮的东西。

2) 对数据过滤后端部分有什么建议吗?我应该使用过滤器调用数据库还是在客户端存储主列表并过滤客户端?

【问题讨论】:

  • 在我看来,您应该基于 QTable 制作自己的组件。您可以使用插槽和控件来实现您的目标。

标签: javascript vue.js vue-component quasar-framework


【解决方案1】:

查看允许列过滤器的新类星体扩展 QGrid。

Github - https://github.com/pratik227/quasar-qgrid

演示 - https://quasar-qgrid.netlify.com/

【讨论】:

    【解决方案2】:

    可以用 Lodash 完成。

    以下代码使用选择或文本输入实现过滤器。

    注意,这只是客户端。

    <template>
      <q-page padding>
          <div class="row q-my-lg">
              <div class="col-3">
              <q-select style="width:250px" filled v-model="dessert" :options="desserts" :label="dessert" stack-label dense @input="filterLocation"></q-select>
              </div>
              <div class="col-2">
                <q-input dense @input="searchByDessert" hint="search by dessert" v-model="dessertName" maxlength="25" ></q-input>
              </div>
          </div>
          <div class="row">
            <div class="col">
              <q-table
                title="Treats"
                :data="data"
                :columns="columns"
                row-key="name"
                :filter="filter"
                :filter-method="filterData"
              ></q-table>
            </div>
          </div>
      </q-page>
    </template>
    
    <script>
    
    const lodash = require('lodash')
    
    export default {
      name: 'PageIndex',
      data () {
        return {
          dessert: '',
          desserts: [],
          dessertName: '',
          filter: { value: '' },
          calorie: '',
          columns: [
            {
              name: 'name',
              required: true,
              label: 'Dessert (100g serving)',
              align: 'left',
              field: row => row.name,
              format: val => `${val}`,
              sortable: true
            },
            { name: 'calories', align: 'center', label: 'Calories', field: 'calories', sortable: true },
            { name: 'fat', label: 'Fat (g)', field: 'fat', sortable: true },
            { name: 'carbs', label: 'Carbs (g)', field: 'carbs' },
            { name: 'protein', label: 'Protein (g)', field: 'protein' },
            { name: 'sodium', label: 'Sodium (mg)', field: 'sodium' },
            { name: 'calcium', label: 'Calcium (%)', field: 'calcium', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) },
            { name: 'iron', label: 'Iron (%)', field: 'iron', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) }
          ],
          data: [
            {
              name: 'Frozen Yogurt',
              calories: 159,
              fat: 6.0,
              carbs: 24,
              protein: 4.0,
              sodium: 87,
              calcium: '14%',
              iron: '1%'
            },
            {
              name: 'Ice cream sandwich',
              calories: 237,
              fat: 9.0,
              carbs: 37,
              protein: 4.3,
              sodium: 129,
              calcium: '8%',
              iron: '1%'
            },
            {
              name: 'Eclair',
              calories: 262,
              fat: 16.0,
              carbs: 23,
              protein: 6.0,
              sodium: 337,
              calcium: '6%',
              iron: '7%'
            },
            {
              name: 'Cupcake',
              calories: 305,
              fat: 3.7,
              carbs: 67,
              protein: 4.3,
              sodium: 413,
              calcium: '3%',
              iron: '8%'
            },
            {
              name: 'Gingerbread',
              calories: 356,
              fat: 16.0,
              carbs: 49,
              protein: 3.9,
              sodium: 327,
              calcium: '7%',
              iron: '16%'
            },
            {
              name: 'Jelly bean',
              calories: 375,
              fat: 0.0,
              carbs: 94,
              protein: 0.0,
              sodium: 50,
              calcium: '0%',
              iron: '0%'
            },
            {
              name: 'Lollipop',
              calories: 392,
              fat: 0.2,
              carbs: 98,
              protein: 0,
              sodium: 38,
              calcium: '0%',
              iron: '2%'
            },
            {
              name: 'Honeycomb',
              calories: 408,
              fat: 3.2,
              carbs: 87,
              protein: 6.5,
              sodium: 562,
              calcium: '0%',
              iron: '45%'
            },
            {
              name: 'Donut',
              calories: 452,
              fat: 25.0,
              carbs: 51,
              protein: 4.9,
              sodium: 326,
              calcium: '2%',
              iron: '22%'
            },
            {
              name: 'KitKat',
              calories: 518,
              fat: 26.0,
              carbs: 65,
              protein: 7,
              sodium: 54,
              calcium: '12%',
              iron: '6%'
            }
          ],
          database: null
        }
      },
      mounted () {
        this.database = this.data
        const desserts = {}
        this.data.forEach(function (element) {
          desserts[element.name] = 1
        })
        this.desserts = Object.keys(desserts)
      },
      methods: {
        searchByDessert (val) {
          if (val === '') {
            this.data = this.this.database
            return this.data
          }
          const needle = val.toLowerCase()
          this.data = lodash.filter(this.database, function (object) {
            return object.name.toLowerCase().indexOf(needle) > -1
          })
        },
        filterLocation (value) {
          this.data = this.database
          this.filter = { value: value }
        },
        filterData () {
          if (this.data.length > 2 && this.filter.value) {
            return lodash.filter(this.data, function (o) {
              return o.name === this.filter.value
            }.bind(this)
            )
          } else {
            return this.data
          }
        }
      }
    }
    </script>
    

    【讨论】: