Reputation: 895
I wonder if I can access computed property in nested loop based on current item. As for now I achieved it by creating a method to get a specific property. Is there a way to do it without this extra method?
EDIT I update my example to make it more clear.
const vm = new Vue({
el: '#app',
data: {
categories: [
{ id: 0, text: 'zero' },
{ id: 1, text: 'one' },
{ id: 2, text: 'two' },
],
minions: [
{ name: 'A', category: 'zero' },
{ name: 'B', category: 'zero' },
{ name: 'C', category: 'one' },
{ name: 'D', category: 'two' },
],
},
methods: {
getComputedData: function (name) {
return this[name];
},
},
computed: {
zero: function () {
return this.minions.filter(({category}) => category === 'zero');
},
one: function () {
return this.minions.filter(({category}) => category === 'one');
},
two: function () {
return this.minions.filter(({category}) => category === 'two');
}
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div id="app">
<div
v-for="category in categories"
>
<h1>{{ category.text }}</h1>
<ul>
<li
v-for="minion in getComputedData(category.text)"
>{{ minion.name }}</li>
</ul>
</div>
</div>
Upvotes: 1
Views: 2268
Reputation: 43881
You can refer to the viewmodel as $root
, so the computeds you have named for your categories are $root[category.text]
. See the snippet below.
If you were in a component, you wouldn't have the special $root
variable, and would have to resort to eval(category.text)
.
In either case, there is a code smell here, as you're making named objects based on data (and your computeds are mostly repeated code). You would do better to create a single computed or function that covers all the categories.
const vm = new Vue({
el: '#app',
data: {
categories: [
{ id: 0, text: 'zero' },
{ id: 1, text: 'one' },
{ id: 2, text: 'two' },
],
minions: [
{ name: 'A', category: 'zero' },
{ name: 'B', category: 'zero' },
{ name: 'C', category: 'one' },
{ name: 'D', category: 'two' },
],
},
computed: {
zero: function () {
return this.minions.filter(({category}) => category === 'zero');
},
one: function () {
return this.minions.filter(({category}) => category === 'one');
},
two: function () {
return this.minions.filter(({category}) => category === 'two');
}
},
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div id="app">
<div
v-for="category in categories"
>
<h1>{{ category.text }}</h1>
<ul>
<li
v-for="minion in $root[category.text]"
>{{ minion.name }}</li>
</ul>
</div>
</div>
Upvotes: 1