In this tutorial, we will explore various options to style Vue.js components using CSS. Please note that this tutorial assumes the use of Vue.js Single File Components.

The simplest way to add CSS to a Vue.js component is by using the style tag, similar to HTML. Here’s an example:

<template>
 <p style="text-decoration: underline">Hi!</p>
</template>

<script>
export default {
  data() {
    return {
      decoration: 'underline'
    }
  }
}
</script>

This method allows for static styling. If you want the underline style to be defined within the component data, you can do it as follows:

<template>
 <p :style="{'text-decoration': decoration}">Hi!</p>
</template>

<script>
export default {
  data() {
    return {
      decoration: 'underline'
    }
  }
}
</script>

In the above code, we use the shorthand :style instead of v-bind:style.

To avoid using quotes for text-decoration, Vue.js enables a camelCase syntax which can be rewritten as textDecoration:

<template>
 <p :style="{textDecoration: decoration}">Hi!</p>
</template>

Instead of binding an object to style, you can reference a computed property:

<template>
 <p :style="styling">Hi!</p>
</template>

<script>
export default {
  data() {
    return {
      textDecoration: 'underline',
      textWeight: 'bold'
    }
  },
  computed: {
    styling: function() {
      return {
        textDecoration: this.textDecoration,
        textWeight: this.textWeight
      }
    }
  }
}
</script>

Vue components generate plain HTML, so you can add a class to each element and define a corresponding CSS selector to style it:

<template>
 <p class="underline">Hi!</p>
</template>

<style>
.underline { text-decoration: underline; }
</style>

You can also use SCSS by specifying the lang attribute:

<template>
 <p class="underline">Hi!</p>
</template>

<style lang="scss">
body {
 .underline { text-decoration: underline; }
}
</style>

To make the class dynamic and apply it only when a certain data property is true, you can bind the class to a component property:

<template>
 <p :class="{underline: isUnderlined}">Hi!</p>
</template>

<script>
export default {
  data() {
    return {
      isUnderlined: true
    }
  }
}
</script>

<style>
.underline { text-decoration: underline; }
</style>

Alternatively, you can directly bind a string to the class, which will reference a data property:

<template>
 <p :class="paragraphClass">Hi!</p>
</template>

<script>
export default {
  data() {
    return {
      paragraphClass: 'underline'
    }
  }
}
</script>

<style>
.underline { text-decoration: underline; }
</style>

You can assign multiple classes by adding two classes to paragraphClass or using an array:

<template>
 <p :class="[decoration, weight]">Hi!</p>
</template>

<script>
export default {
  data() {
    return {
      decoration: 'underline',
      weight: 'weight',
    }
  }
}
</script>

<style>
.underline { text-decoration: underline; }
.weight { font-weight: bold; }
</style>

You can also use an object within the class binding:

<template>
 <p :class="{underline: isUnderlined, weight: isBold}">Hi!</p>
</template>

<script>
export default {
  data() {
    return {
      isUnderlined: true,
      isBold: true
    }
  }
}
</script>

<style>
.underline { text-decoration: underline; }
.weight { font-weight: bold; }
</style>

Combining the two statements is also possible:

<template>
 <p :class="[decoration, {weight: isBold}]">Hi!</p>
</template>

<script>
export default {
  data() {
    return {
      decoration: 'underline',
      isBold: true
    }
  }
}
</script>

<style>
.underline { text-decoration: underline; }
.weight { font-weight: bold; }
</style>

Furthermore, you can use a computed property that returns an object, which is useful when adding multiple CSS classes to the same element:

<template>
 <p :class="paragraphClasses">Hi!</p>
</template>

<script>
export default {
  data() {
    return {
      isUnderlined: true,
      isBold: true
    }
  },
  computed: {
    paragraphClasses: function() {
      return {
        underlined: this.isUnderlined,
        bold: this.isBold
      }
    }
  }
}
</script>

<style>
.underlined { text-decoration: underline; }
.bold { font-weight: bold; }
</style>

It’s important to note that any CSS that is not hardcoded (like in the first example) will be processed by Vue.js, which automatically prefixes the CSS to ensure compatibility with older browsers.