vue.js 尝试根据输入筛选数组

soat7uwm  于 2023-03-03  发布在  Vue.js
关注(0)|答案(2)|浏览(133)

我有一个具有不同值的文档数组。下面是一个简化的示例:

documents: [
 {
    name: 'Some name',
    type: 'PDF',
    tags: [
        'tag 1',
        'tag 2',
        'tag 3'
    ],
    dateOfCreation: 'DD/MM'
  },
  {
    name: 'Some name',
    type: 'Excel',
    tags: [
        'tag 4',
    ],
    dateOfCreation: 'DD/MM'
  },
  {
    name: 'Some name',
    type: 'Word',
    tags: '',
    dateOfCreation: 'DD/MM'
  }
]

我正在创建两个输入字段。一个有一个显示文档类型的下拉列表,另一个有一个显示每个文档的标签的下拉列表。我的目标是当用户从下拉列表中选择一个类型或标签时,文档数组将被过滤,只显示具有该特定类型或标签的文档。
我已经用类型完成了这一点。
我创建了一个名为documentTypes的json文件,其中存储了文档可以具有的不同类型值。

[
  "pdf",
  "word",
  "excel"
]

我有一个vue输入字段,它与一个名为filteredDocumentType的空变量进行了双向绑定,对于我的输入选项,它循环遍历包含不同文档类型的json文件。

<b-form-group class="mt-4">
    <b-form-select v-model="filteredDocumentType">

      <template>
        <b-form-select-option :value="null" disabled>-- 'Select document by type' --</b-form-   select-option>
      </template>

      <b-form-select-option :value="'all'">-- All --</b-form-select-option>

      <option v-for="documentType in documentTypes" :key="documentType" :value="documentType">
        {{ $t('model.document.types.' + documentType) }}
      </option>

    </b-form-select>
  </b-form-group>

然后我创建了一个计算属性来获取documents数组并检查输入和类型。如果没有选择类型或者用户选择了“all”,那么所有文档都会显示在列表中,但是如果有可用的类型并且用户选择了一个,那么列表就会被过滤,只显示特定类型的文档。

filteredDocuments() {
        if (this.filteredDocumentType === null || this.filteredDocumentType === 'all') {
          return (this.documents ?? []).filter(document =>
            (document.name.toUpperCase().includes(this.search.toUpperCase()) ||
                 this.$t(`model.document.types.${document.type}`).toUpperCase().includes(this.search.toUpperCase())))
    }
        else {
          return (this.documents ?? []).filter(document =>
            (document.name.toUpperCase().includes(this.search.toUpperCase()) ||
               this.$t(`model.document.documentTypes.${document.type}`).toUpperCase().includes(this.search.toUpperCase())) &&
        document.type === this.filteredDocumentType)
        }

这是可行的,但是我想对标签做同样的事情,但是我没有把我的标签存储在json文件中,正如你在数组中看到的,每个文档可以有多组标签,我不能为它们创建一个json文件,因为它们是由用户在前端的不同位置输入的。
如果我创建了一个名为documentTags的json文件,并手动将用户标记添加到列表中,然后导入它,那么我可以使用相同的方法:

filteredDocuments() {
    if (this.filteredDocumentType === null || this.filteredDocumentType === 'all') {
      return (this.documents ?? []).filter(document =>
        (document.name.toUpperCase().includes(this.search.toUpperCase()) ||
             document.tags[0].toUpperCase().includes(this.search.toUpperCase())))
}
    else {
      return (this.documents ?? []).filter(document =>
        (document.name.toUpperCase().includes(this.search.toUpperCase()) ||
           document.tags[0].toUpperCase().includes(this.search.toUpperCase())) &&
    document.tags[0] === this.filteredDocumentType)
    }

以及

<b-form-group class="mt-4">
        <w-b-form-select v-model="filteredDocumentType">

          <template>
            <b-form-select-option :value="null" disabled>-- {{ 
    $t('selectDocumentByType') }} --</b-form-select-option>
          </template>

          <b-form-select-option :value="'all'">({{ $t('all') }})</b- 
   form-select-option>

          <option v-for="documentTag in documentTags" 
    :key="documentTag" :value="documentTag">
            {{ documentTag }}
          </option>

        </w-b-form-select>
      </b-form-group>

但是如果我不想使用json文件,我应该循环通过什么呢?我需要循环通过包含标记的嵌套数组,并且确保过滤掉任何带有空标记的文档,以确保我没有得到空白的输入字段。
以下方法无效:

<option v-for="documentTag in documents.tags" :key="documentTag" :value="documentTag">
    {{ documentTag }}
  </option>

还尝试了以下操作:

<option v-for="documentTag in document.tags[0]" :key="documentTag" :value="documentTag">
    {{ documentTag }}
  </option>
3htmauhk

3htmauhk1#

我建议使用Computed Property来存储标记列表

每次“文件”变更时,将由Vue计算。

computed: {

    uniqueTags(){
        const uniqueTagsSoFar = [];
        this.documents.forEach(document => {
            if (document && document.tags && document.tags.length>0){
                document.tags.forEach(tag=>{
                    if (!uniqueTagsSoFar.includes(tag)){
                        tags.push(tag)
                    }
                })
            }
        });
        return uniqueTagsSoFar
    }

}

然后,在你的程序中,把this.uniqueTags当作一个变量,它将是一个标签列表,不包括“",并且每个标签只列出一次。

mklgxw1f

mklgxw1f2#

获取computed属性中的标记的一种方法:

const documents = [
 {
    name: 'Some name',
    type: 'PDF',
    tags: [
        'tag 1',
        'tag 2',
        'tag 3'
    ],
    dateOfCreation: 'DD/MM'
  },
  {
    name: 'Some name',
    type: 'Excel',
    tags: [
        'tag 4',
        'tag 1',
        'tag 3'    ],
    dateOfCreation: 'DD/MM'
  },
  {
    name: 'Some name',
    type: 'Word',
    tags: '',
    dateOfCreation: 'DD/MM'
  }
]
const tags = documents.reduce((r,s) => {
  if (s.tags.length) r.push(s.tags)
  return r;
}, []).flat()
console.log([...new Set(tags)])

相关问题