I have a simple Vue application that is structured as follows: I have an App.vue component and a Card.vue component

In my App.vue I have created the following data:

        {
          id: 1,
          name: "Frenkie de Jong",
          position: "midfielder",
          country: "The Netherlands",
          image: "frenkie_de_jong.jpg",
          value: 20000000,
          club_id: 2
        },
        {
          id: 2,
          name: "Mathijs de Ligt",
          position: "defender",
          country: "The Netherlands",
          image: "mathijs_de_ligt.jpg",
          value: 20000000,
          club_id: 2
        }....
      ],
      clubs: [
        { id: 1, name: "Liverpool", logo: "Liverpool.png" },
        { id: 2, name: "Ajax Amsterdam", logo: "ajax_amsterdam.png" }
      ...
      ] 

For each player, I'm creating a card, which shows all relevant information (value, country, etc.). This is already working using a v-for from the App.vue.

However, now I would also like to show the club of each player. The clubs are linked to the player with the club_id's. What would be the best practice to do this?

I was thinking of one of the two following options:

  1. Find a match for the club in App.vue: iterate over all players and if the player.club_id == club.id, we send through the player and the club to the Card component and create a new card.
  2. Find a match for the club in Card.vue: iterate over all players and for each player, send through the player and the list of all clubs to the Card component. In Card.vue I then need to create a function which finds the match between the two.

What would be the best way of doing this (in terms of performance)? Or are there maybe better options?

Thanks in advance!

Jeroen

2 Answers

0
Community On Best Solutions

Map your club data as object so you don't have to perform find operation for each player, It will give you club in O(1) time rather than O(n) e.g make a computed prop mappedClubs and pass it in player cards

mappedClubs(){
  return this.clubs.reduce((r,c) =>{
   r[c.id] = r
   return r
  },{})
}

and in your card component just access club information something like that

<div> club name : {{ mappedClubs[player.club_id].name}} </div>
0
Andrei Gătej On

One thing you can do in order to avoid a second iteration is to use a Map for the clubs.

data () {
 return {
  players: [/* ... */],
  clubs: new Map([
   [1, { name: "Liverpool", logo: "Liverpool.png" }],
   [2, { name: "Ajax Amsterdam", logo: "ajax_amsterdam.png" }]
  ])
 }
}

So that you can use this method in order to get the club information depending on the provided clubId.

methods: {
  getClubById (clubId) {
   return this.clubs.get(clubId)
 }
}

Putting it all together:

<Card 
 v-for="player in players"
 :key="player.id"
 :playerClub="getClubById(player.club_id)"
/>

I personally like this approach more as you have to iterate over the players array only once, and getting a specific club requires O(1) time complexity.(Here is more about this)