如何使用Vue搜索排序列表中的多个属性

时间:2017-12-06 17:09:31

标签: javascript vue.js vuejs2 lodash

我有一个包含人名和姓的数据集,我希望用户能够使用Vue 2搜索这些数据。

到目前为止,我设法首先按名字排序列表,然后使用Lodash按姓氏排序,我还设法按类型对它们进行分类。现在我想过滤/搜索(我不知道正确的单词)数组,只显示姓名(或部分名称)或姓名或两者的人与输入字段的内容相匹配。

香草JS解决方案与Lodash解决方案一样受到赞赏!

props: {
  people: {
    type: Array,
    required: true
  }
},

data: function(){
  return {
    filter: '',
    people:[{
      "FirstName" : "Stefan",
      "LastName" : "Braun",
      "Type" : "EN",
    },
    {
      "FirstName" : "Jenny",
      "LastName" : "Smith",
      "Type" : "VO",
    },
    {
      "FirstName" : "Susan",
      "LastName" : "Jones",
      "Type" : "EN",
    }]
  }
}

methods: {

  matchingType: function (people, type) {
    people = this.alphabeticallyOrdered(this.searchFiltered(people))

    return people.filter(function (person) {
      return person.Type == type
    })
  },

  alphabeticallyOrdered: function(arr){
    return _.orderBy(arr, ['FirstName', 'LastName'])
  },

  searchFiltered: function(arr){
    filter = this.filter
    return _.some(arr, _.unary(_.partialRight(_.includes, this.filter)));
  }
},

template: `
  <div>
    <input type="text" model="filter"></input>
    <div v-for="type in types" class="type" :class="type.short">
      <h2 class="type-name">{{type.long}}</h2>
      <div class="people">
        <div v-for="person in matchingType(people, type.short)" class="person">
          <div class="personal-details">
            <p class="h2">{{person.FirstName}}</p>
            <p class="h4">{{person.LastName}}</p>
          </div>
        </div>
      </div>
    </div>
  </div>
`

1 个答案:

答案 0 :(得分:4)

通常,您可以使用computed property来处理此问题。

这是一个例子。我在你的例子中消除了很多额外的代码,因为有些部分我无法复制而不知道你在做什么(你没有发布组件的填充代码),但实质上,你会写一个计算机如下所示的属性,并在模板中迭代它。

console.clear()

new Vue({
 el: "#app",
  data:{
     people:[{
      "FirstName" : "Stefan",
      "LastName" : "Braun",
      "Type" : "EN",
    },
    {
      "FirstName" : "Jenny",
      "LastName" : "Smith",
      "Type" : "VO",
    },
    {
      "FirstName" : "Susan",
      "LastName" : "Jones",
      "Type" : "EN",
    }],
    filterText: null
  },
  computed:{
    filteredPeople(){
      // If there is no filter text, just return everyone
      if (!this.filterText) return this.people
      
      // Convert the search text to lower case
      let searchText = this.filterText.toLowerCase()
      
      // Use the standard javascript filter method of arrays
      // to return only people whose first name or last name
      // includes the search text
      return this.people.filter(p => {
        // if IE support is required and not pre-compiling,
        // use indexOf instead of includes
        return p.FirstName.toLowerCase().includes(searchText) ||
        p.LastName.toLowerCase().includes(searchText)  
      })
    }
    
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.9/vue.min.js"></script>
<div id="app">
  <input type="text" v-model="filterText">
  <ul>
    <li v-for="person in filteredPeople">
      {{person.FirstName}}  {{person.LastName}}
    </li>
  </ul>
</div>