vue.js 类星体表列过滤

r8xiu3jd  于 2023-10-23  发布在  Vue.js
关注(0)|答案(3)|浏览(130)

1)有没有一种方法可以实现类似于数据表的类星体表列过滤?https://datatables.net/extensions/fixedheader/examples/options/columnFiltering.html
理想情况下,它将是一个自动填充文本字段,它将过滤表中的所有行。我有一个25列的表,所以想要一些强大的东西。
2)对数据过滤后端部分有什么建议吗?我应该用过滤器调用DB,还是在客户端和过滤器客户端存储一个主列表?

c0vxltue

c0vxltue1#

看看新的类星体扩展QGrid,它允许列过滤器。
Github - https://github.com/pratik227/quasar-qgrid
演示-https://quasar-qgrid.netlify.com/

idfiyjo8

idfiyjo82#

这可以通过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>
l7wslrjt

l7wslrjt3#

您还可以扩展现有的Q表,在其标题槽中具有Q输入。输入创建filter对象,该对象被变换为filterTerms的数组。数组在内部传递给q-table的filterMethod,你可以用它来做实际的过滤。
你可以在stackblitz上查看我的demo。我很确定造型还可以再改进。
这只是开始我很确定你可以修改代码,以自动poulate的q输入字段。至于过滤客户端/服务器端,这在很大程度上取决于你的实际用例。如果它是几个100行然后我不认为在浏览器中做过滤的问题。

// parent.vue
<template>
 <FilterTable dense flat :columns="columns" :rows="rows" />
</template>
// FilterTable.vue
<template>
  <q-table :filterMethod="filterMethod" :filter="filterTerms">
    <template v-slot:header="slotProps">
      <q-tr :props="slotProps">
        <q-th v-for="col in slotProps.cols" :key="col.name" :props="slotProps">
          <q-input v-model.trim="filter[col.name]" @click.stop />
          {{ col.label }}
        </q-th>
      </q-tr>
    </template>
  </q-table>
</template>

<script setup>
import { computed, reactive } from 'vue'

let filter = reactive({})
let filterTerms = computed(() => {
  return getFilterTerms(filter)
})

const getFilterTerms = (filter) => {
  // TODO values are not guaranteed to be in order of property creation
  // see https://stackoverflow.com/questions/30076219
  return Object.entries(filter).map((entry) => {
    return { column: entry[0], value: entry[1] }
  })
}

const filterMethod = (rows, terms) => {
  for (const term of terms) {
    rows = rows.filter((row) => {
      if (('' + row[term.column]).startsWith('' + term.value)) {
        return true
      }

      return false
    })
  }
  return rows
}
</script>

相关问题