Reputation: 30035
I have and Array of Objects whose elements are randomly ordered. I would like to list the values in a specific order (of the keys).
As an example, the iteration below just lists them:
var vm = new Vue({
el: "#root",
data: {
all: [{
second: 2,
third: 3,
first: 1
},
{
third: 30,
first: 10,
second: 20
}
],
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script>
<div id="root">
<div v-for="a in all">
<div v-for="(v, k) in a">{{v}}</div>
</div>
</div>
Is this possible to drive the iteration so that it is ordered according to a list of keys (["first", "second", third"]
) which would yield
1
2
3
10
20
30
Upvotes: 6
Views: 12377
Reputation: 937
In Module 5 of my Vue.js Training course, I actually discuss this. At first glance, the Object.keys
approach may seem like the correct approach. However, different JavaScript engines return the properties in different orders. For that reason, you can't rely on it.
In Vue.js, you could either a) sort your Array when the Array gets populated b) Create a "computed property" or c) Create a sort method that you can pass your property into.
In my opinion, you should use option b. The reason why is because computed properties get cached. By doing this, you'll only run your sort code once. However, if you were to use option c the sort would execute during each iteration. Option a is a possibility, but I don't know enough about your scenario to know if this is a real option or not.
Upvotes: 0
Reputation: 15566
I don't know vue but you can do it like this in javascript.
<div v-for="k in Object.keys(a).sort()">{{k}}:{{a[k]}}</div>
Also note that alphabetic sorting accidentally fits into your need, but you might need a custom sort function like sort((a,b)=>order.indexOf(a)-order.indexOf(b))
with your custom order order: ["first","second","third","fourth"]
which may not be alphabetic.
var vm = new Vue({
el: "#root",
data: {
all: [{
second: 2,
third: 3,
first: 1,
fourth: 4
},
{
third: 30,
first: 10,
second: 20,
fourth: 40
}
],
order: ["first","second","third","fourth"]
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script>
<div id="root">
<div v-for="a in all">
<div v-for="k in Object.keys(a).sort((a,b)=>order.indexOf(a)-order.indexOf(b))">{{k}}:{{a[k]}}</div>
<hr/>
</div>
</div>
Upvotes: 11
Reputation: 21505
You can put your list of sorted keys in an array and v-for
over that instead.
<div v-for="a in all">
<div v-for="key in presortedListOfKeys">
{{a[key]}}
</div>
</div>
Upvotes: 4
Reputation: 1030
You can use computed properties and get the all
sorted first before iteration through them.
Upvotes: 1