Set a variable inside a v-for loop on Vue JS
Asked Answered
J

1

15

I have a v-for loop with vue.js on a SPA and I wonder if it's posible to set a variable at the beginning and then just print it everytime you need it, because right now i'm calling a method everytime i need to print the variable.

This is the JSON data.

{
"likes": ["famiglia", "ridere", "caffè", "cioccolato", "tres leches", "ballare", "cinema"],
"dislikes":["tristezze", "abuso su animali", "ingiustizie", "bugie"]

}

Then I use it in a loop:

<template>
<div class="c-interests__item" v-for="(value, key) in interests" :key="key" :data-key="key" :data-is="getEmotion(key)" >

// NOTE: I need to use the variable like this in different places, and I find myself calling getEmotion(key) everythime, is this the way to go on Vue? or there is another way to set a var and just call it where we need it?

<div :class="['c-card__frontTopBox', 'c-card__frontTopBox--' + getEmotion(key)]" ...
<svgicon :icon="getEmotion(key) ...

</div>
</template>

<script>
import interests from '../assets/json/interests.json'
... More imports

let emotion = ''

export default {
  name: 'CInfographicsInterests',
  components: {
    JSubtitle, svgicon
  },
  data () {
    return {
      interests,
      emotion
    }
  },
  methods: {
    getEmotion (key) {
      let emotion = (key === 0) ? 'happy' : 'sad'
      return emotion
    }
  }
}
</script>

// Not relevanty to the question
<style lang='scss'>
.c-interests{...}
</style>
  1. I tried adding a prop like :testy="getEmotion(key)" and then { testy } with no luck...

  2. I tried printing { emotion } directly and it doesn't work

So, there is anyway to acomplish this or should i stick calling the method every time?

Thanks in advance for any help.

Jevon answered 17/7, 2018 at 17:16 Comment(0)
R
14

It's not a good idea to use methods inside a template for non-user-directed actions (like onClicks). It's especially bad, when it comes to performance, inside loops.

Instead of using a method, you can use a computed variable to store the state like so

computed: {
  emotions() {
    return this.interests.map((index, key) => key === 0 ? 'happy' : 'sad');
  }
}

This will create an array that will return the data you need, so you can use

<div class="c-interests__item"
    v-for="(value, key) in interests"
    :key="key" />`

which will reduce the amount of times the item gets re-drawn.

Rouse answered 17/7, 2018 at 18:29 Comment(4)
Thanks, I’ll give it a go tomorrow and let you know how it goesJevon
I'm curious though, why the use of data-is and data-key? Seems like you may be using another library here. If that's the case, consider sticking to one as you may create some conflict.Rouse
Oh no, sorry that’s just for me to see what the items are returning :) kind of a console.logJevon
Hi, it worked as expected, from vue inspector I saw you created a new array within the computed function, since my JSON is not that complex I realized I could just return a JSON already with the keys as this : interestsLoop: { 'happy': interests.likes, 'sad': interests.dislikes } But your answer is still really helpful and I learned new stuff which is the important thing, Thanks a lot.Jevon

© 2022 - 2024 — McMap. All rights reserved.