当标题中使用过滤功能时,搜索在 Vuetify 数据表中不起作用

won*_*r95 5 javascript datatable search vuejs2 vuetify.js

我有一个 Vue 组件,其中包含 Vuetify v-data-table组件。它使用带有<v-text-field>. 我遇到的问题是,使用filter作为道具传递到数据表的标头中的函数会阻止搜索功能工作。

数据表组件使用body-prepend槽来定义用于过滤表内容的选择列表。

 <v-data-table
      show-expand
      :headers="headers"
      :items="items"
      :search="search"
      item-key="sow"
      hide-default-footer
      dense
      disable-pagination
    >
      <template v-slot:top>
        <v-toolbar flat color="white">
          <v-toolbar-title>{{ title }}</v-toolbar-title>
          <v-spacer></v-spacer>
          <v-text-field
            v-model="search"
            prepend-icon="search"
            label="Search"
            single-line
            hide-details
            clearable
          ></v-text-field>
        </v-toolbar>
      </template>
      <template v-slot:body.prepend>
        <tr>
          <td :colspan="7"></td>
          <td v-if="showStatusFilter">
            <v-select
              v-model="selectedStatuses"
              :items="statuses"
              :menu-props="{ maxHeight: '400' }"
              label="Select Status"
              multiple
              chips
              deletable-chips
              small-chips
              dense
            ></v-select>
          </td>
          <td v-if="showPracticeFilter">
            <v-select
              v-model="selectedPractices"
              :items="practices"
              label="Select Practice"
              multiple
              chips
              deletable-chips
              small-chips
              dense
            ></v-select>
          </td>
          <td v-if="showSEFilter">
            <v-select
              v-model="selectedSEs"
              :items="ses"
              label="Select SE"
              multiple
              chips
              deletable-chips
              small-chips
              dense
            ></v-select>
          </td>
        </tr>
      </template>
    </v-data-table>
Run Code Online (Sandbox Code Playgroud)

然后 headers 从父组件传入到组件中

headers: [
  { text: 'SOW', align: 'left', value: 'sow' },
  { text: 'Firm', value: 'firm' },
  { text: 'Category', value: 'category' },
  { text: '% Complete', value: 'percentComplete' },
  { text: 'Estimated Completion', value: 'estimatedCompletionDate' },
  { text: 'Amount', value: 'amount' },
  {
    text: 'Status',
    value: 'status',
    filter: (f) => {
      if (this.getSelectedStatuses.length === 0) return true
        return this.getSelectedStatuses.indexOf(f + '') !== -1
      }
    },
    {
      text: 'Practice',
      value: 'practice'
      filter: (f) => {
        if (this.getSelectedPractices.length === 0) return true
          return this.getSelectedPractices.indexOf(f + '') !== -1
        }
      },
  { text: 'Modified', value: 'modified' },
  { text: 'Actions', value: 'actions' }
],
Run Code Online (Sandbox Code Playgroud)

Vuex 用于存储过滤后的值,以便可以在数据表组件的实现之间使用过滤器。

这样实施后,该search领域就悄然消亡了。但是,一旦我filterheaders数组对象中删除函数,它就可以正常工作。我需要以filter不同的方式实现这些功能吗?或者它应该像我设置的那样工作吗?例如,我是否需要将filter函数动态添加到headers数据表包装组件内的数组项,而不是将其作为 prop 的一部分传递?

小智 0

他们多次更改了 v-data-table 上的过滤功能。它在 Vuetify 2 中几乎被破坏了,并且无法修复。问题11600。这是我在 Vuetify@2.6.15 中绕过这个问题的方法

语境:

v-data-table 采用这些与问题相关的属性

  • 搜索: 字符串
  • 标题:{过滤器:(值:未知,搜索:字符串,项目:未知)=> 布尔值}[]

您在 header 属性中提供的自定义过滤器 fn 使您看起来可以按列进行过滤。然而,这些函数似乎毫无用处,因为它们仅在搜索属性更改时触发,与正常的表范围过滤函数相比,没有提供任何语法糖的好处。IMO 应将其删除以避免最初的混乱。它们仅对表范围的搜索字符串属性起作用。

我通过将所有输入过滤器字段转换为单个 json 字符串,然后使用该字符串作为搜索词,使其按列工作。

(请注意,示例样式使用 mx-4 具有正确的间距)

<v-data-table
  item-key="id"
  :items="items"
  :headers="headers"
  :search="searchterm"
  :custom-filter="() => true"
>
  <template #body.prepend>
    <td><v-text-field class="mx-4 mb-2" v-model="filters.name" label="name" /></td>
    <td><v-text-field class="mx-4 mb-2" v-model="filters.age" label="age" /></td>
  </template>
</v-data-table>
Run Code Online (Sandbox Code Playgroud)
// vue.data
filters = {
  name: null,
  age: null
}

//vue.computed
get searchterm (): string {
  return JSON.stringify(this.filters)
}

//vue.data
headers = [{
  value: 'name',
  filter: (value: unknown, searchterm: string) => {
    const filter = JSON.parse(searchterm)?.name
    if (!filter) return true
    return value === filter
  }
}, {
  value 'age',
  filter: (value: unknown, searchterm: string) => {
    const filter = JSON.parse(searchterm)?.age
    if (!filter) return true
    return value === filter
  }
}]
Run Code Online (Sandbox Code Playgroud)