1

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>
Adrian Baran
  • 885
  • 7
  • 23
  • Seems like in your case `computed` is not really necessary, unless you have a specific use case? – kevguy Oct 08 '17 at 10:01
  • Hi @kevguy A snippet is there just to show what I mean by access to computed property in nested loop. As you suggested, I don't need computed properties here at all. I wonder though if it's possible if needed. – Adrian Baran Oct 08 '17 at 10:10
  • @kevguy I update my example so to be more specific – Adrian Baran Oct 08 '17 at 10:14
  • 1
    Even with the updated specific use case, `computed` is still not necessary, just put what you have in the `computed`s into your `getComputedData` method, and you're done. Therefore, maybe "computed property in nested loop" is not really a necessity since always a cleaner solution can be thought of?? – kevguy Oct 08 '17 at 10:59
  • Please correct me if I'm wrong: computed properties are cached (https://vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods) and if I just move what I have in `computed` to `getComputedData` it won't behave the same way (unless I make my own caching). The purpose of this question is not how to solve it better, but if it's possible at all to access computed properties if such scenario without creating extra method. – Adrian Baran Oct 08 '17 at 15:26

1 Answers1

1

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>
Roy J
  • 42,522
  • 10
  • 78
  • 102
  • Thanks @Roy J. I completely agree with your point regarding code smell here. I just wanted to see if such thing is possible :) – Adrian Baran Oct 08 '17 at 15:29