首页 > 解决方案 > Vue 2 过滤器不是一个函数

问题描述

试图用输入过滤一组对象。到目前为止,我已经尝试了多种方法,但都没有运气。它告诉我我的函数“clients.filter”不是一个函数。如果我将代码设置为“list.filter”,则会收到相同的消息,搜索的输入实际上是一个单独组件的一部分,我不确定这是否是我的问题。见下文

这是我从 api 收集客户端并列在数据表中的组件

<template>
 <table class="table table-bordered table-light table-striped table-hover">
    <thead class="thead-primary">
      <tr>
          <th scope="col">#</th>
          <th scope="col">Name</th>
          <th scope="col">Type</th>
          <th scope="col">Email</th>
          <th scope="col">Phone</th>
          <th scope="col">Profile</th>
      </tr>
    </thead> 
        <tbody class="client-info">
            <tr v-for="(client, index) in filterBy(clients, searchClient)"  :key="index">
                <td>{{ index }}</td>
                <td>{{ client.name }}</td>
                <td>{{ client.type }}</td>
                <td>{{ client.email }}</td>
                <td>{{ client.phone }}</td>
                <td><router-link v-bind:to="'/client/'+client.id"><i class="far fa-eye"></i></router-link></td>
            </tr>
        </tbody>
    </table>
</template>

<script>


export default {
    name: 'client-info',
    props: {
        clients: {
            type: Array,
            default: () => []
        }
    },
    data() {
        return {
        searchClient: ''
        }
    },
    created() {
    this.$store.dispatch('retrieveClients')
    },
    computed: { 
     filterBy (clients, value) {
         return clients.filter( client => {
             console.log(this.clients)
             return client.name.indexOf(value) > -1;
      })
    }
  }

}
</script>

next 是实际显示列表的父组件。我相信我的结构已经关闭,因为我使用的是 vuex。但无论如何我不确定为什么它告诉我的“clients.filter”不是一个函数。

<template>
 <div>

<!-- this is the buttons and filter above the list -->
    <div class="d-flex mb-3">.
      <input class="form-control w-25" placeholder="Filter By Name" v-model="searchClient" type="search">
      <div class="mr-auto ml-2">
        <button class="btn btn-outline-primary dropdown-toggle dropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
        <span>Type:</span>
          All
        </button>
        <div class="dropdown-menu dropdown-menu-left">
          <a class="dropdown-item" href="#">Business</a>
          <a class="dropdown-item" href="#">Individual</a>
        </div>
      </div>         

      <div class="btn-group ml-auto">
        <button class="btn btn-outline-secondary"><i class="fas fa-print"></i></button>
        <button class="btn btn-outline-success">Import <span><i class="fas fa-download"></i></span></button>
        <button class="btn btn-outline-danger">Export <span><i class="fas fa-upload"></i></span></button>
        <router-link to="/add" class="btn btn-primary pt-2">Add Client</router-link>
      </div>

    </div>


    <!-- the clients data is imported from client info file -->
    <div>      
      <client-info :clients="allClients"></client-info>      
    </div>



 </div>
</template>

<script>
import { mapGetters } from 'vuex'
import ClientInfo from '@/components/clientslistexperience/ClientInfo'


export default {
name: 'ClientsList',
  components: {
    ClientInfo
  },
  data() {
    return {
      searchClient: ''
    }
  },
  computed: {
    ...mapGetters(['allClients']),
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">



</style>

我尝试的另一个选项是这样定义我的计算方法

filterClient () {
         return this.clients.filter( client => {
             return !this.searchClient || client.name.toLowerCase().includes(this.searchClient.toLowerCase()) > -1
      })
    }

然后也改变我的 v-for

<tr v-for="(client, index) in filterClient"  :key="index">
                <td>{{ index }}</td>
                <td>{{ client.name }}</td>
                <td>{{ client.type }}</td>
                <td>{{ client.email }}</td>
                <td>{{ client.phone }}</td>
                <td><router-link v-bind:to="'/client/'+client.id"><i class="far fa-eye"></i></router-link></td>
            </tr>

但仍然没有运气,尽管我没有得到这个定义的警报,但我也没有得到任何结果。任何帮助都是极好的!!

标签: vue.jsvuejs2vue-componentvuex

解决方案


使用时

props: {
    list: {
        type: Array,
        default: () => []
    }
},

使用默认值一个空数组意味着如果你定义一个组件而不传递一个列表属性,那么 vue 将使用该默认值。

例如,如果您定义了这样的组件:

<template>
    <ul>
        <li v-for="(item, index) in list" :key="index">{{item}}</li>
    </ul>
</template>

export default {
    name: 'MyList',
    props: {
        list: {
            type: Array,
            default: () => [1, 2, 3],
        },
    },
};

然后定义一个组件实例,如:

<my-list></my-list>

您的组件将呈现:

<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>

但是,如果您像这样定义组件实例:

<my-list :list="['a', 'b', 'c']"></my-list>

您的组件将呈现:

<ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
</ul>

鉴于此,在不知道您的 retrieveClients 操作的情况下,我只能假设您传递给“clients”道具的“allClients”值不是数组,因此过滤器函数不存在。

如果 allClients 是状态属性,请确保您的操作将状态更改为至少一个空数组。否则,如果 allClients 是一个 getter,请确保它至少返回一个空数组。


推荐阅读