Home > Back-end >  Using computed value in v-for (Vue.js)
Using computed value in v-for (Vue.js)

Time:12-18

I'm currently making bitcoin trading web app (personal project. Not a business one)

I have a bunch of cryptocurrencies prices from API, and showing it all by using v-for loop.

here's part of my code:

    <tbody >
      <tr v-for="coin in props.coins" :key="coin.code" >
        <td >
          <div >{{ coin.name }}</div>
          <div >{{ coin.code }}</div>
        </td>
        <td
          
        >{{ Number(coin.trade_price).toLocaleString() }}</td>
        <td
          :
          
        >
          <div>{{ Number(coin.signed_change_rate).toFixed(2) }}%</div>
          <div >{{ coin.signed_change_price }}</div>
        </td>
        <td >{{ convertTp24h(coin.acc_trade_price_24h) }}</td>
        <td >
          <button >매수</button>
        </td>
      </tr>
    </tbody>

As you can see I have many methods and expressions that converts raw value from API to human-readables.

I'm wondering if this is a bad practice. I heard that methods are called everytime so, rather use computed().

But as you can see I have my values from API in Object(props.coins) and I'm looping this object in v-for. Can I still use computed() methods to convert a value inside an Object that is also looped by v-for?

CodePudding user response:

You can't use computed for items in a loop, since they don't take in arguments. Computed is used for .. computed properties and methods take in arguments e.g. formatChangeRate()

You are right that methods are called everytime, but that's totally fine and normal practice.

So creating a component with methods like formatChangeRate, formatTradePrice is totally fine.

There are ways to make it work with computed properties but in my opinion its not worth it.

1) You coould make another component that takes in the item as a prop, uses computed property and displays it in componenent's template but that's a total overhead.

2) You could map the array and reference it by index. Something like:

computed: {
  changeRate() {
    this.coins.map(coin => {
      return Number(coin.signed_change_rate).toFixed(2)   '%'
    })
  }
}

Now changeRate is an array of formatted change rates so you could in your v-for do something like

v-for="(coin, index) in coins)">
<td>changeRate[index]</td>

So now you're looping through the array multiple times, and the code is less testable and less readable.

In my opinion using methods is totally fine and the right way to go in this example. The performance of calling a simple formatting method multiple times is negligible.

Also the cache you're refering to is that computed properties are cached based on their reactive dependency. E.g. you have in your data, firstName and lastName. You could then make a computed property called fullName that concats those two. The caching would work so that fullName doesn't change unless firstName or lastName changes.

Since you're looping through an array the value that would be computed is always changing.

CodePudding user response:

you are right, methods are called everytime and in theory thats not really good, but in practice if your method just concat strings or other simple operations, that's really not a big deal. Your computer can do millions of operations like that per seconds.

In the other hand if you do complex operations then the solution is to precalculate before. After you receive your data construct an Array looking something like bellow and use this one in your template

(pseudo code)
[{
    name,
    code,
    changeRate: Number(signed_change_rate).toFixed(2),
    ...
},
...
]
  • Related