Reputation: 4462
I don't know how to sort an already computed array of results.
In Vue, I filter images by their ratio. Now I want to sort the individual results by date, name or whatever is possible.
I tried sorting the array with a method, but this solution does not automatically recalculate and dynamically display the sorted results.
data() {
return {
results: [],
imgProperties: {
imgId: [],
imgRatio: [],
imgCreateDate: []
}
};
},
computed: {
resultsFiltered() {
if (this.sliderVal == 0) {
return this.results;
} else {
const obj = [];
const arr = [];
for (let i = 0; i < this.ratioIndeces.length; i++) {
const element = this.ratioIndeces[i];
obj.push(this.results[element]);
arr.push(this.imgProperties.imgRatio[element]);
}
return obj;
}
}
},
There is no sort approach to be seen here.
I would like to know how or where to start.
The code example shows an excerpt of the current structure. The ratio is calculated in the methods.
I would like to sort the array by imgCreateDate
and imgRatio
.
Upvotes: 2
Views: 11380
Reputation: 2993
Example of sorting by imgRatio
:
<p v-for="result in resultsFiltered | orderBy 'imgRatio'">{{ result.imgRatio }}</p>
or
<p v-for="result in resultsFiltered">{{ result.imgRatio }}</p>
computed: {
resultsFiltered() {
if (this.sliderVal == 0) {
return this.results.sort((a, b) => { return b.imgRatio - a.imgRatio;});
} else {
const obj = [];
const arr = [];
for (let i = 0; i < this.ratioIndeces.length; i++) {
const element = this.ratioIndeces[i];
obj.push(this.results[element]);
arr.push(this.imgProperties.imgRatio[element]);
}
return this.obj.sort((a, b) => { return b.imgRatio - a.imgRatio;});
}
}
},
For Vue2 you can reference on here
Upvotes: 2
Reputation: 4462
here is my latest approach to filter the results and sort them by parameters at the same time:
computed: {
resultsFiltered () {
return this.built.dataset.filter(img => {
return this.customFilters.every(key => {
const parameter = this.params[key]
const args = parameter.map(val => this.customInputs[val]).slice(1)
return filterMenus[key](img[parameter[0]], ...args)
})
}).sort(this.sortings[this.sortDirection][this.sortType])
}
},
the single elements:
built.datatset
= is an array of objects. Each img is an object.
customFilters
= is an array with filter options. like 'ratio' or 'keyword'. So I can filter with every key I got in the list.
customInputs
= whatever the user types in. A date range, a ratio, a keyword, a year, ...
sortings
= compare img1 to img2
sortDirection
= up or down. like 'img2.ratio - img1.ratio'
sortType
= alphabetical, numerical, by date or reset to default view
Upvotes: 0
Reputation: 10857
If your computed property makes use of a data property to control the sort, you could do it like so. First, I created data that includes my original, unsorted data, and a current sort:
data: {
origItems:[
{name:'ray', age:10},
{name:'apple', age:20},
{name:'zula', age:9},
],
sortType:''
},
Then I built my computed to return values based on sortType:
computed:{
items() {
if(this.sortType === '') return this.origItems;
if(this.sortType === 'name') {
return this.origItems.sort((a,b) => {
if(a.name < b.name) return -1;
if(a.name > b.name) return 1;
return 0;
});
}
if(this.sortType === 'age') {
return this.origItems.sort((a,b) => {
if(a.age < b.age) return -1;
if(a.age > b.age) return 1;
return 0;
});
}
}
This could probably be written tighter. I used this layout for testing:
<div id="app" v-cloak>
<button @click="sort('name')">Sort by Name</button>
<button @click="sort('age')">Sort by Age</button>
<ul>
<li v-for="item in items">{{ item.name}} - {{ item.age }}</li>
</ul>
</div>
You can see an online example of this here: https://codepen.io/cfjedimaster/pen/eYYMVWr?editors=1011
Upvotes: 1