在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
});
}
})
答案 0 :(得分:13)
在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;
})
}
}
目前有两种方式。在所有情况下,模板看起来都一样。
<input v-model="searchQuery">
<span v-if="!filteredItems.length">No results.</span>
<ul>
<li v-for="item in filteredItems"></li>
</ul>
通过filterBy
访问原始$options
方法。
computed: {
filteredItems: function () {
return this.$options.filters.filterBy(this.items, this.searchQuery);
}
}
有点清洁的方法。 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));
}
}
答案 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年后仍尝试修复它)
/* 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;