Objects pro

An item in an object can be treated as a regular variable in many ways. When you use an array of objects to create a list, you can use the object’s variables not only to render their values. You can use them as a source property for images, to render conditional elements, and to add conditional styles too.

Following the example from the previous article, a list of recent chats can be extended to show

  • avatars,
  • unread dot indicators,
  • bold darker fonts for unread chats:

To achieve this, every object must have two additional variables—one for storing a link to a photo and another for storing the unread status:








 
 






 
 






 
 





data: {
  contacts: [
    {
      nameFirst: 'Joe',
      nameLast: 'Cole',
      message: 'Have they heard of Klimt anyway?',
      time: '12:15 AM',
      unread: true,
      photo: 'https://images-na.ssl-images-amazon.com/images/M/MV5BMTc2NjczMzQwMV5BMl5BanBnXkFtZTgwNTczMzcxNjE@._V1_UY256_CR42,0,172,256_AL_.jpg'
    },
    {
      nameFirst: 'Michael B.',
      nameLast: 'Jordan',
      message: 'No way! Thursday was supposed...',
      time: '8:37 AM',
      unread: true,
      photo: 'https://m.media-amazon.com/images/M/MV5BMjExOTY3NzExM15BMl5BanBnXkFtZTgwOTg1OTAzMTE@._V1_UX172_CR0,0,172,256_AL_.jpg'
    },
    {
      nameFirst: 'Linnea',
      nameLast: 'Berthelsen',
      message: 'You: sounds good!',
      time: '8:04 AM',
      unread: false,
      photo: 'https://images-na.ssl-images-amazon.com/images/M/MV5BN2JhY2M2Y2QtZDBjOS00MjY2LWJhMjEtZWNjNTQ3MTE0YzBlXkEyXkFqcGdeQXVyNjE5MDgzMjI@._V1_UY256_CR10,0,172,256_AL_.jpg'
    },
    //..
  ]
}

So far you have used variables in objects only to render data:

<div>
  {{contact.nameFirst}} {{contact.nameLast}}
</div>
<div>
  {{contact.time}}
</div>
<div>
  {{contact.message}}
</div>

It’s time to explore other applications.

Image source

Variables inside objects can be used to render images the same way you would use a regular variable as an image source:


 


<div v-for="contact in contacts">
  <img :src="contact.photo">
</div>

This template-container takes values of the photo variables from each object in the contacts array and uses them in :src property to provide URLs for images:

Conditional rendering

You can make elements of your template render conditionally the same way you do it outside of lists—with v-if and conditions. Here’s how an unread indicator can be coded:



 
 
 


<div v-for="contact in contacts" class="py-3 flex">
  <div>{{contact.nameFirst}} {{contact.nameLast}}</div>
  <div v-if="contact.unread">
    <div class="w-2 h-2 bg-teal-500 rounded-full mt-2 ml-3"></div>
  </div>
</div>

The object’s variable unread is used for the condition that determines the rendering of the indicator. According to this condition, objects with unread equal to true will render a container with a colored dot:

Conditional style

Finally, an object’s variable can be used for conditional styling. The code below applies different styles to read and unread items:


 



 


 




<div v-for="contact in contacts" class="my-3">
  <div :class="{'font-bold': contact.unread}">
    {{contact.nameFirst}} 
    {{contact.nameLast}}
  </div>
  <div :class="{'text-gray-500': !contact.unread}">
    {{contact.time}}
  </div>
  <div :class="{'text-gray-500': !contact.unread}">
    {{contact.message}}
  </div>
</div>

This template container uses the same variable unread that’s used in the conditional rendering above. Here it’s used inside the conditional :class attribute so that font-bold will be applied to names if unread is true and text-gray-500 will be applied to a message and a timestamp if it is false:

Color hierarchy in Tailwind

Another way to manage different text colors for a message and a date stamp is to apply grey by default with class="text-gray-500" and conditionally make them black with :class="{'black': contact.unread}". Unfortunately, this will not work. We use Tailwind as a stylesheet, and the styles for the text-gray-500 class are defined below the styles for text-black on the stylesheet. This means that text-gray-500 has greater precedence and will always overrule text-black when both classes are applied.

Keep in mind that colors are defined in a particular order. The way colors are presented in Tailwind's official docs represents their precedence with black having the lowest precedence and pink having the hightest.

Practice

Extended cars catalog

Create a grid of cards with images and conditional styles and labels:

  1. Use your results from the Cars catalog task in the previous article as a starting file, or start from scratch.
  2. Extend the existing array with the phone, isOnSale and isSoldOut boolean variables. You can also copy this array:
cars: [
  {
    make: "GMC",
    model: "Savana 3500",
    description: "volutpat sapien arcu sed augue",
    year: 2006,
    isOnSale: true,
    isSoldOut: false,
    photo: 'https://file.kbb.com/kbb/vehicleimage/housenew/480x360/2010/2010-gmc-savana%203500%20cargo-frontside_gmsav101.jpg'
  },
  {
    make: "Volvo",
    model: "940",
    description: "luctus ultricies eu nibh quisque id justo",
    year: 1992,
    isOnSale: false,
    isSoldOut: false,
    photo: 'https://cdcssl.ibsrv.net/autodata/images/?IMG=U2VLGEC1.jpg&width=390'
  },
  {
    make: "BMW",
    model: "3 Series",
    description: "natoque penatibus et magnis dis parturient",
    year: 2011,
    isOnSale: true,
    isSoldOut: false,
    photo: 'https://d1ix0byejyn2u7.cloudfront.net/drive/images/made/drive/images/remote/https_f2.caranddriving.com/images/new/large/BMW3Series0908(3)_794_529_70.jpg'
  },
  {
    make: "Mitsubishi",
    model: "Mighty Max",
    description: "tellus nisi eu orci mauris lacinia",
    year: 1986,
    isOnSale: false,
    isSoldOut: false,
    photo: 'https://car-pictures.cars.com/images/?IMG=U2MIGEH1.JPG&height=369&autotrim=1'
  },
  {
    make: "Kia",
    model: "Optima",
    description: "imperdiet nullam orci pede venenatis non sodales",
    year: 2007,
    isOnSale: false,
    isSoldOut: true,
    photo: 'http://carphotos.cardomain.com/ride_images/3/613/3021/26531510002_large.jpg'
  },
  {
    make: "Mercedes-Benz",
    model: "R-Class",
    description: "libero rutrum ac lobortis vel dapibus at",
    year: 2012,
    isOnSale: false,
    isSoldOut: true,
    photo: 'https://media.ed.edmunds-media.com/mercedes-benz/r-class/2011/oem/2011_mercedes-benz_r-class_wagon_r350-4matic_fq_oem_1_500.jpg'
  }
]
  1. Inside the template-container, connect the img container to the photo variable inside the array's objects with the :src attribute.
  2. Inside the template-container, create 2 containers: one with the text “ON SALE” and another with “SOLD OUT”. Make them conditional, based on the values of the variables isOnSale and isSoldOut.
  3. Apply conditional styles to the text for items that have isSoldOut equal to true.