Vue.js为空过滤结果

时间:2015-09-23 15:23:46

标签: vue.js

在Vue中,我必须过滤一些数据:

<input v-model="search">
<ul>
    <li v-repeat="photo in photos | filterBy search in 'name'">
        <img src="{{ photo.src }}" alt="{{ photo.name }}">
    </li>
    <li v-if="!photos.length">
        No results, sorry!
    </li>
</ul>

如何检测空的过滤结果并向用户显示相应的消息?

修改

我目前正在执行以下操作,我觉得这是一个hacky解决方法:

HTML:

<input v-model="search">
<ul>
    <li v-repeat="photo in photos">
        <img src="{{ photo.src }}" alt="{{ photo.name }}">
    </li>
    <li v-if="!photos.length">
        No results, sorry!
    </li>
</ul>

Javascript:

var v = new Vue({
    data: {
        allPhotos: [...],
        photos: [],
        search: '',
    },
    ready: function () {
        var filter = Vue.filter('filterBy');
        var self = this;
        this.$watch('search', function () {
            self.photos = filter(self.allPhotos, self.search, 'name');
        }, {
            immediate: true
        });
    }
})

4 个答案:

答案 0 :(得分:13)

Vue 2.x(更新)

在Vue 2.x过滤器现在只能在文本插值中使用as docs say

  

Vue 2.x过滤器只能在胡子绑定中使用。要在指令绑定中实现相同的行为,您应该使用Computed属性。

您可以使用JavaScript内置filter方法和计算属性来实现相同的行为。

<input v-model="searchQuery">

<span v-if="!filteredItems.length">No results.</span>

<ul>
    <li v-for="item in filteredItems"></li>
</ul>
computed: {
  filteredItems: function () {
    var self = this;
    return self.items.filter(function (item) {
      return item.indexOf(self.searchQuery) !== -1;
    })
  }
}

Vue 1.x(原始答案)

目前有两种方式。在所有情况下,模板看起来都一样。

<input v-model="searchQuery">

<span v-if="!filteredItems.length">No results.</span>

<ul>
    <li v-for="item in filteredItems"></li>
</ul>

filterBy

通过filterBy访问原始$options方法。

computed: {
    filteredItems: function () {
        return this.$options.filters.filterBy(this.items, this.searchQuery);
    }
}

$ EVAL

有点清洁的方法。 Eval表达式就像在模板中一样。

computed: {
  filteredItems: function () {
    return this.$eval('items | filterBy searchQuery');
  }
}

答案 1 :(得分:8)

在HTML中:

<input v-model="search">
<h4 v-if="!filteredPhotos.length">No results</h4>
<ul>
    <li v-for="photo in filteredPhotos">
        <img :src="photo.src" :alt="photo.name">
    </li>
</ul>

在JS中,您需要使用这样的计算属性:

computed: {
  filteredPhotos: function () {
      return this.photos.filter(function(photo){
          return photo.name.indexOf(this.search) > -1;
      }.bind(this));
  }
}

演示:http://jsfiddle.net/crswll/Lr9r2kfv/37/

答案 2 :(得分:2)

这只适用于Vue 1.0,即使这样你也应该使用计算属性。我会在这里留下这个答案以防万一。

您也可以使用vm.$eval和计算属性来执行此操作。

computed: {
  filteredItems: function () {
    return this.$eval('items | filterBy searchQuery');
  }
}

并使用类似

的内容
<div v-if="filteredItems.length">
  <div v-for="item in filteredItems">
    {{ item.name }}
  </div>
</div>
<div v-else>
  No results found!
</div>

答案 3 :(得分:0)

HTML / CSS解决方案(以防万一,如果您在2年后仍尝试修复它)

&#13;
&#13;
/* all list items are visible */
ul.that-list li { display: block; }

/* ...exept last one*/
ul.that-list li:last-child { display: none; }

/* but if last one is also first one ... means the only one */
ul.that-list li:first-child { display: block; }
&#13;
<h2>List with items</h2>
<ul class="that-list">
  <!-- here is your v-for with any filters you want -->
  <li>1 - Item is here</li>
  <li>2 - Another One Here</li>
  <li>3 - And anothe one</li>
  <!-- this is your message -->
  <li>(!message) There is no items... sorry</li>
</ul>

<h2>Empty</h2>
<ul class="that-list">
  <!-- v-for with no rendered items :c -->
  <li>(!message) There is no items... sorry</li>
</ul>
&#13;
&#13;
&#13;

Also codepen link here