使用Vue2搜索过滤

时间:2017-12-13 15:45:41

标签: javascript vuejs2

    <!-- Facets in the v-for below is an array of objects, each element (facet) in the
    facets array has a property which is an array of facetItems. -->

    <div class="row" v-for="(facet, facetsIndex) in facets" :key="facetsIndex">

      <!-- Since we are inside the v-for, it creates a search input for each facet.
      Each facet search input will only search for facetItems belonging to that facet.
      We know which facet to search in because we pass the facetIndex to the searchFilter function. -->

      <input type="text" @keyup="searchFilter(facetsIndex)">

      <div v-if="facet.facetItems.length > 0">
        <div class="facet-header">{{config[core.toLowerCase()].displayNames[facet.facetName]}}</div>
        <div class="row facet-scroll" >

          <!-- The v-for below is used to iterate over the facetItems for each facet. displayFacetItems() is called
          for each array of facetItems corresponding to each facet on initial render. displayFacetItems() is also called
          on each keyup event emitting from the corresponding facet search input. displayFacetItems() should return an
          array of facetItems objects, and when a search input is entered, it should return a filtererd array of facetItems
          based on the search results. -->

          <div  class="facet-item" v-for="(item, facetItemIndex) in displayFacetItems(facetsIndex)" :key="facetItemIndex">
            <facet v-bind:item="item"  v-bind:facet="facet"></facet>
          </div>

        </div>
        <hr class="divider"/>
      </div>
    </div>

    methods: {
      searchFilter (facetsIndex) {
        let searchTerm = event.currentTarget.value
        this.displayFacetItems(facetsIndex, searchTerm)
      },
      displayFacetItems (facetsIndex, searchTerm) {
        if (!searchTerm) return this.facets[facetsIndex].facetItems
        return this.facets[facetsIndex].facetItems.filter((facetItem) => {
          return _.includes(facetItem.name.toLowerCase(), searchTerm.toLowerCase())
        })
      }
    },

请参阅上面代码中的注释,以了解我的代码中发生的事情。

我不明白为什么上面的代码不起作用。我试图为每个方面实现搜索功能。搜索时,只应对属于该特定方面的facetItem进行过滤。

我已经能够验证displayFacetItems是否确实返回了一个已过滤的facetItem数组,但由于某种原因,已过滤的数组未在DOM中更新。

这可能与Vue的数据绑定或Vue更新DOM的过程有关。我非常感谢任何关于我做错事的指示。

我的代码从这篇文章中获得灵感:

https://nickescobedo.com/1018/introduction-to-vue-js-filtering-with-lodash

2 个答案:

答案 0 :(得分:0)

param facetsIndex不是被动的,请看看你的jsconsole,你应该对此有一个警告,不仅如此,你的代码逻辑是完全错误的。

  • 您可以在输入中使用v模型,
  • 创建一个filteredFacets属性
  • 在循环中使用此属性。

举个例子,您应该阅读有关VueJS如何工作的更多信息: https://vuejs.org/v2/guide/

答案 1 :(得分:0)

您可以在Vuejs上查看我的jsfiddle搜索项目。我希望这会对你有所帮助。

<div id="app">
    <label>
        Search name: <input type="text" v-model='searchString'>
    </label> <br>
    <transition-group tag='ul' name='my-list'>
        <li v-for='item in filteredList' :key='item.id' class="my-list-item">
            {{item.name}}
        </li>
    </transition-group>
</div>
<script>
   const app = new Vue({
    el: '#app',
    beforeMount() {
        const req = fetch('https://jsonplaceholder.typicode.com/users');
        req.then(response => {
            if (response.ok) {
                return response.json();
            }
            throw new Error('Bad request: ' + response.status);
        })
        .then(users => {
            this.users = users;
            this.nextId = this.users.length + 1;
        });
    },
    data: {
        searchString: '',
        users: [
        {id: 1, name: 'Alex'},
        {id: 2, name: 'Bob'},
        {id: 3, name: 'Sandy'},
        ],
    },
    computed: {
        filteredList: function() {
            const searchString = this.searchString.toLowerCase();
            return this.users.filter(item => item.name.toLowerCase().includes(searchString));
        }
    }
});
</script>