简体   繁体   中英

I have 6 object properties called item1, item2 up to item6 which are not in an array I can loop through. How to DRY my code?

I am using Vue.js on my front-end and have the following code:

<div class='participant' v-for='(participant, index) in match.details.participants'>
    <div class='items'>
        <img :src="'http://ddragon.leagueoflegends.com/cdn/9.13.1/img/item/' + participant.stats.item0 + '.png'" alt="">
        <img :src="'http://ddragon.leagueoflegends.com/cdn/9.13.1/img/item/' + participant.stats.item1 + '.png'" alt="">
        <img :src="'http://ddragon.leagueoflegends.com/cdn/9.13.1/img/item/' + participant.stats.item2 + '.png'" alt="">
        <img :src="'http://ddragon.leagueoflegends.com/cdn/9.13.1/img/item/' + participant.stats.item3 + '.png'" alt="">
        <img :src="'http://ddragon.leagueoflegends.com/cdn/9.13.1/img/item/' + participant.stats.item4 + '.png'" alt="">
        <img :src="'http://ddragon.leagueoflegends.com/cdn/9.13.1/img/item/' + participant.stats.item5 + '.png'" alt="">
    </div>
</div>

While there's nothing wrong with it, it's annoying me that I have to repeat almost the same identical line of code 6 times. The only difference is in the image src which is determined by the values of item0, item1 to item5 properties of the participant object. This is why I was wondering if I could use a loop to create each <img> tag and just change the number after the item based on which iteration of the loop it is. Sadly I can't use v-for="item in items" since the item0, item1 to item5 are not in array. They're just object properties.

From your descriptions, I guess you participants look like this:

[
  { name: "yasio", stats: {
    item0: "renewable potion",
    item1: "long sword",
    item2: "empty_slot",
    item3: "empty_slot", 
    item4: "empty_slot",
    item5: "empty_slot"
  }},

  { name: "master yu", stats: {
    item0: "BF sword",
    item1: "empty_slot",
    item2: "empty_slot",
    item3: "empty_slot",
    item4: "empty_slot",
    item5: "empty_slot" }}
];

If you change the stats to also be an array, you can use that loop you say. There's not really a reason to have an object with 6 properties named 0 to 5, since that's basically an array.

So I would use either:

[
  { name: "yasio", stats: [
    "renewable potion",
    "long sword",
    "empty_slot",
    "empty_slot",
    "empty_slot",
    "empty_slot"
  ]},

  { name: "master yu", stats: [
    "BF sword",
    "empty_slot",
    "empty_slot",
    "empty_slot",
    "empty_slot",
    "empty_slot"
  ]}
];

and then use the index.

Or if you want to save more information about the item:

[
  { name: "yasio", stats: [ 
    { name: "renewable potion", damage: -150 },
    { name: "long sword", damage: 10 }
  ]},
  { name: "master yu", stats: [
    { name: "BF sword", damage: 40}
  ]}
];

Collections of things are easier to work with if they are arrays. And things themselves can be objects then, so each thing can have multiple properties.

If you need direct access to certain collection items, you can always reduce the collection back into an object with the name as the property.

You need to use a v-for with a range, like this :

<img v-for="i in 6" :src="'http://ddragon.leagueoflegends.com/cdn/9.13.1/img/item/' + participant.stats.item + (i - 1) + '.png'" alt=""> *

v-for with a range in vue start at 1, which is why you'd have to say (i - 1)

Using ES6 :

<img v-for="i in 6" :src="`http://ddragon.leagueoflegends.com/cdn/9.13.1/img/item/${participant.stats.item}${i - 1}.png`" alt=""> 

As your stats.item starts with 0, we do index - 1 as index in Vue 2.x starts from 1. You can use it like this:

<div class='participant' v-for='(participant, index) in match.details.participants'>
    <div class='items'>
        <img :src="`http://ddragon.leagueoflegends.com/cdn/9.13.1/img/item/${participant.stats.item}${index - 1}.png`" alt="">
    </div>
</div>

Edit :

It's unclear to me if the OP wants 6 images per participant or 1. This is an answer if the OP wants 1 image per participant

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM