我有一个Vue.js应用程序。在这个应用程序中,我试图动态地将过滤器值应用于Array
个对象。数组中的每个对象都有字段。我试图通过字段值过滤这些对象。每个字段都可以通过多个值进行过滤。
目前,我一直未能确定如何进行此过滤。我尝试过使用JavaScript的filter
功能。但是,这总是为我返回一个空结果集。我已将此Fiddle放在一起,其中包含以下代码:
new Vue({
el: '#app',
data: {
currentFilterProperty: '',
currentFilterValue: '',
cols: [
{ title: 'Name', prop:'name' },
{ title: 'Age', prop:'age' },
{ title: 'Birthday', prop:'birthday' },
],
dataFilters: [],
data: [
{ name:'Patricia Miller', age:69, birthday:'04-15-1948' },
{ name:'Bill Baggett', age:62, birthday:'05-07-1955' },
{ name:'Maxine Thies', age:21, birthday:'11-28-1995' },
{ name:'Alison Battle', age:65, birthday:'08-07-1952' },
{ name:'Dick Triplett', age:25, birthday:'08-27-1982' }
]
},
methods: {
addFilter: function() {
var f = this.dataFilters[this.currentFilterProperty];
if (!f) {
this.dataFilters = {};
this.dataFilters[this.currentFilterProperty] = [ this.currentFilterValue ];
} else {
this.dataFilters[this.currentFilterProperty].push(this.currentFilterValue);
}
// How to apply filter?
}
}
})
我不确定如何将过滤器应用于data
对象。
答案 0 :(得分:7)
完整的解决方案。最佳测试:添加过滤器年龄62,然后生日04-15-1948,然后添加名称Patricia中的'tri'。
new Vue({
el: '#app',
data: {
filteredProperty: 'name',
query: '',
activeFilters: [],
data: [
{name: 'Patricia Miller', age: 62, birthday: '04-15-1948'},
{name: 'Bill Baggett', age:62, birthday: '04-15-1948' },
{name:'Maxine Thies', age:62, birthday:'11-28-1948'},
{name:'Alison Battle', age:65, birthday:'08-07-1952'},
{name:'Dick Triplett', age:25, birthday:'08-27-1982'}
]
},
computed: {
filtered () {
var filtered = this.data
this.activeFilters.forEach(filter => {
filtered = filtered.filter(record => {
return filter.name === 'name'
? new RegExp(filter.value, 'i').test(record[filter.name])
: record[filter.name] == filter.value
})
})
return filtered
}
},
methods: {
addFilter () {
this.activeFilters.push({
name: this.filteredProperty,
value: this.query
})
this.query = ''
},
removeFilter (idx) {
this.activeFilters.splice(idx, 1)
}
}
})
<div id="app">
<div>
<select v-model="filteredProperty">
<option value="name">Name</option>
<option value="age">Age</option>
<option value="birthday">Birthdate</option>
</select>
<input placeholder="filter value" v-model="query">
<button @click="addFilter">add filter</button>
</div>
<hr>
<table v-if="activeFilters.length">
<tr style="width: 100px">
<th colspan="3">Filters in use:</th>
</tr>
<tr v-for="(filter, index) in activeFilters" :key="index">
<td>{{ _.capitalize(filter.name) }}:</td>
<td>{{ filter.value }}</td>
<td style="padding-left: 10px;">
<a href="#" @click.prevented=removeFilter(index)>
remove
</a>
</td>
</tr>
</table>
<hr v-if="activeFilters.length">
<table>
<tbody>
<tr v-for="(record, index) in filtered" :key="index">
<td style="padding-right:18px;">{{ record.name }}</td>
<td style="padding-right:18px;">{{ record.age }}</td>
<td>{{ record.birthday }}</td>
</tr>
</tbody>
</table>
</div>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/lodash"></script>
答案 1 :(得分:0)
看看下面的代码。将您的方法更改为计算属性,然后过滤器可以自动发生而无需按下按钮。小提琴总是按名称进行过滤,因此您需要进行一些调整以适应所有过滤条件,但它应该让您朝着正确的方向前进。
new Vue({
el: '#app',
data: {
currentFilterProperty: '',
currentFilterValue: '',
cols: [
{ title: 'Name', prop:'name' },
{ title: 'Age', prop:'age' },
{ title: 'Birthday', prop:'birthday' }
],
data: [
{ name:'Patricia Miller', age:69, birthday:'04-15-1948' },
{ name:'Bill Baggett', age:62, birthday:'05-07-1955' },
{ name:'Maxine Thies', age:21, birthday:'11-28-1995' },
{ name:'Alison Battle', age:65, birthday:'08-07-1952' },
{ name:'Dick Triplett', age:25, birthday:'08-27-1982' }
]
},
computed:{
filteredData(){
var self = this;
// Add condition for currentFilterProperty == 'Name'
if(this.currentFilterValue != undefined && this.currentFilterValue != ''){
return this.data.filter(function(d){
//alert(d.name + " " + this.currentFilterValue);
return d.name.indexOf(self.currentFilterValue) != -1;
});
}
// else if(currentFilterProperty == 'Date'){
// return this.data.filter(function(d){
//return d.birthday.indexOf(self.currentFilterValue) != -1;
// });
else{
return this.data;
}
}
}
})
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.4/vue.min.js"></script>
<div id="app">
<div>
<select v-model="currentFilterProperty">
<option v-for="c in cols" :value="c.prop">{{c.title}}</option>
</select>
<input placeholder="filter value" v-model="currentFilterValue" />
</div>
<hr />
<table>
<tbody>
<tr v-for="(record, index) in filteredData">
<td style="padding-right:18px;">{{ record.name }}</td>
<td style="padding-right:18px;">{{ record.age }}</td>
<td>{{ record.birthday }}</td>
</tr>
</tbody>
</table>
</div>
&#13;
答案 2 :(得分:0)
这是工作解决方案通过检查captaining
条件
new Vue({
el: '#app',
data: {
currentFilterProperty: 'name',
currentFilterValue: '',
filteredData:[],
cols: [
{ title: 'Name', prop:'name' },
{ title: 'Age', prop:'age' },
{ title: 'Birthday', prop:'birthday' },
],
dataFilters: [],
addFilters:[],
data: [
{ name:'Patricia Miller', age:69, birthday:'04-15-1948' },
{ name:'Bill Baggett', age:62, birthday:'05-07-1955' },
{ name:'Maxine Thies', age:21, birthday:'11-28-1995' },
{ name:'Alison Battle', age:65, birthday:'08-07-1952' },
{ name:'Dick Triplett', age:25, birthday:'08-27-1982' }
]
},
methods: {
addFilter: function() {
if(!this.currentFilterValue){
return false;
}
var obj = {};
this.addFilters.push({name:this.currentFilterProperty,value:this.currentFilterValue});
this.currentFilterValue = "";
var vm = this;
this.dataFilters = this.data
//var temp = [];
for(var i in vm.addFilters){
this.dataFilters = this.dataFilters.filter(function(a,b){
return ((a[vm.addFilters[i].name]).toString().toLowerCase()).indexOf((vm.addFilters[i].value).toString().toLowerCase()) !== -1;
});
}
// How to apply filter?
}
},
mounted(){
this.dataFilters = this.data;
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<div>
<select v-model="currentFilterProperty">
<option value="name">Name</option>
<option value="age">Age</option>
<option value="birthday">Birthdate</option>
</select>
<input placeholder="filter value" v-model="currentFilterValue" />
<button v-on:click="addFilter">
add filter
</button>
</div>
<div v-for="(filter,index) in addFilters">{{filter.name}} : {{filter.value}}</div>
<hr />
<table>
<tbody>
<tr v-for="(record, index) in dataFilters">
<td style="padding-right:18px;">{{ record.name }}</td>
<td style="padding-right:18px;">{{ record.age }}</td>
<td>{{ record.birthday }}</td>
</tr>
</tbody>
</table>
</div>