Dynamic Classes

In Vue.js it is possible to bind the class attribute on an element to data values. This can allow us to more easily toggle class assignments from within our component logic. By altering the classes on components we can cause visual changes to happen when the user interacts with our application, or call the user's attention to some part of the interface that has been updated.

These techniques are not unique to Vue.js; many frameworks allow similar kinds of class toggling and binding.

Binding Data to class attributes

We often have a situation where we wish to apply a class when a specific condition is true. For example, when showing a list of items with "Favorite" buttons, it would be useful to be able to apply a class when the user clicked to add an item to their "Favorites." We see this kind of interface all the time.

To bind data to class attributes we can use the v-bind directive. The binding of values works the same when using it with a class/style attribute as with other attributes, but Vue.js can interpret specific object structures to fill in the proper class/style changes. Here is an example of how a favorite button might indicate whether or not it has been clicked:

<button v-bind:class="{ favorited: isFavorite }" v-on:click="toggleFavorite">Favorite</button>

We can see in this example that we have used v-bind to bind the class attribute to a JavaScript object. The object defines a favorited property, and the value of the property is isFavorite. (The isFavorite value is defined as part of the component's data object, and it is toggled via the toggleFavorite method.) Whenever isFavorite equals true, the favorited class will be applied to this element. Whenever isFavorite is false, the favorited class will be removed.

We can use objects with multiple properties to add/remove multiple classes to an object in the same way. Each property should point to a boolean value that will either be true or false. This value can be altered through any normal means in our code.

For the vast majority of cases, being able to add/remove specific classes is a useful way of altering the visual appearance of an element. However, sometimes we encounter situations where binding the style attribute itself is required in order to achieve our desired effect.

Binding Data to style attributes

In some cases, we want to use some dynamic data to actually alter the style of an element. This is often required when writing complex applications such as data dashboards or browser-based games. But there is a more simple case that often requires us to directly insert a style definition: Placing the user's avatar in the background of an element. This method can be advantageous because we can more easily crop and control the display of avatars that might have differing dimensions.

Here is an example using v-bind to bind the data value for a user profile image to the background of a style:

<template>
  <div>
    <div class="avatar" v-bind:style="{ backgroundImage: 'url('+ user.image +')' }">
      {{ user.username }}
    </div>
  </div>
</template>

<script>
export default {
  name: 'ProfileImage',
  data () {
    return {
      user: {
        username: 'shawnr',
        image: 'http://lorempixel.com/400/400/animals/'
      }
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.avatar {
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center center;
  background-color: #666;
  color: white;
  text-align: center;
  padding: 10px;
  width: 200px;
  height: 200px;
  border-radius: 50%;
}
</style>

We can see that this component displays a profile image. It uses a data object called user to provide the username and the URL for the user avatar image. We have defined the styles to shape the avatar image and control its size, but we cannot write a style definition that includes the user's specific image URL. Instead, we must apply the image URL to the background-image style property for the div.avatar element.

To accomplish this, we bind another data object to the style property. This time, Vue.js knows to read the properties of the data object looking for terms that correspond to CSS properties. Please note: We can use either "kebab case" (with dashes, like background-image) or "camel case" (with capital letters, like backgroundImage) to reference CSS properties. Vue.js will map these properties and their values to CSS properties and insert them into the style attribute. The end result in our example looks like this:

User Avatar with Dynamic Background
User Avatar with Dynamic Background

Using this technique, we gain a lot of flexibility. We can define the data object in our template, or we can define a data object in our component logic and then reference the name of that object in the template. We can set up event listeners to dynamically change values based on user interactions, which can then be translated into visual effects on the screen. This opens the door for all sorts of interesting interface concepts and designs.

results matching ""

    No results matching ""