Vue.js 空筛选结果
Vue.js empty filter results
在 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>
如何检测空过滤器结果并向用户显示适当的消息?
编辑
我目前正在执行以下操作,我认为这是一个棘手的解决方法:
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
});
}
})
在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));
}
}
Vue 2.x(更新)
在 Vue 中 2.x 现在只能使用过滤器,as docs say,内部文本插值:
Vue 2.x filters can only be used inside mustache bindings. To achieve the same behavior inside directive bindings, you should use Computed properties instead.
您可以使用 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>
过滤
通过 $options
.
访问的原始 filterBy
方法
computed: {
filteredItems: function () {
return this.$options.filters.filterBy(this.items, this.searchQuery);
}
}
$评估
更简洁的方法。 Eval 表达式就像您在模板中所做的那样。
computed: {
filteredItems: function () {
return this.$eval('items | filterBy searchQuery');
}
}
这只适用于 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>
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; }
<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>
在 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>
如何检测空过滤器结果并向用户显示适当的消息?
编辑
我目前正在执行以下操作,我认为这是一个棘手的解决方法:
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
});
}
})
在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));
}
}
Vue 2.x(更新)
在 Vue 中 2.x 现在只能使用过滤器,as docs say,内部文本插值:
Vue 2.x filters can only be used inside mustache bindings. To achieve the same behavior inside directive bindings, you should use Computed properties instead.
您可以使用 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>
过滤
通过 $options
.
filterBy
方法
computed: {
filteredItems: function () {
return this.$options.filters.filterBy(this.items, this.searchQuery);
}
}
$评估
更简洁的方法。 Eval 表达式就像您在模板中所做的那样。
computed: {
filteredItems: function () {
return this.$eval('items | filterBy searchQuery');
}
}
这只适用于 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>
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; }
<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>