Tari Ibaba

Tari Ibaba is a software developer with years of experience building websites and apps. He has written extensively on a wide range of programming topics and has created dozens of apps and open-source libraries.

How to Use the Vuetify Slider Component

Sliders are a great way of getting user input from a range of values. There are used for various functions like adjusting the brightness of a display or tuning speaker volumes. In this post, we’re going to explore the various ways we can create and customize sliders with Vuetify.

The v-slider Component

Vuetify provides the v-slider component for creating sliders:

<template>
  <v-app>
    <v-row justify="center" class="mt-2">
      <v-col sm="6">
        <v-slider></v-slider>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Creating a slider with the v-slider component.

A basic slider consists of a track (the long line) and a thumb (the circle). Clicking somewhere on the track moves the thumb to that location:

Clicking on a point on the track moves the thumb there.

Slider Labels

To describe our sliders to users, we can specify a label with the label prop:

<template>
  <v-app>
    <v-row justify="center" class="mt-2">
      <v-col sm="6">
        <v-slider label="Slider"></v-slider>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
A Vuetify slider with a label.

Slider Hints

We can show hints for a slider with the hint prop.

<template>
  <v-app>
    <v-row justify="center" class="mt-2">
      <v-col sm="6">
        <v-slider label="Slider" hint="hint"></v-slider>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

The hint shows up when you click the thumb:

Two-way Binding with v-model

We can use v-model to create a two-way binding between the slider value and a variable.

<template>
  <v-app>
    <div class="d-flex justify-center mt-2">
      <v-col sm="6">
        <v-slider label="Slider" hint="hint" v-model="sliderValue"></v-slider>
      </v-col>
    </div>
    <div class="d-flex justify-center">
      <v-col sm="6">Slider value: {{ sliderValue }}</v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    sliderValue: 0,
  }),
};
</script>

In the code above, we’re adding in some text to display the current value of the slider (determined by sliderValue):

A slider with text below it to display its numeric value.

When the slider receives input sliderValue is updated and the text reflects this:

The text is updated with the new slider value when it changes.

Let’s add a “Reset” button:

<template>
  <v-app>
    <div class="d-flex justify-center mt-2">
      <v-col sm="6">
        <v-slider label="Slider" hint="hint" v-model="sliderValue"></v-slider>
      </v-col>
    </div>
    <div class="d-flex justify-center">
      <v-col sm="6">Slider value: {{ sliderValue }}</v-col>
    </div>
    <div class="d-flex justify-center">
      <v-col sm="6"
        ><v-btn color="primary" @click="sliderValue = 0"
          >Reset slider</v-btn
        ></v-col
      >
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    sliderValue: 0,
  }),
};
</script>
Adding a "Reset" button.

We added a click handler to the button that sets sliderValue to 0 when it is clicked:

Clicking the "Reset" button sets the slider value back to 0 when it is clicked.

Slider Min and Max Values

Vuetify sliders have default min and max values of 0 and 100 respectively. We can change them to something else with the min and max props:

<template>
  <v-app>
    <div class="d-flex justify-center mt-2">
      <v-col sm="6">
        <v-slider
          label="Slider"
          hint="hint"
          v-model="sliderValue"
          min="20"
          max="60"
        ></v-slider>
      </v-col>
    </div>
    <div class="d-flex justify-center">
      <v-col sm="6">Slider value: {{ sliderValue }}</v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    sliderValue: null,
  }),
};
</script>

Now the minimum value of the slider is 20:

The minimum value of the slider is now 20.

And the maximum value is now 60:

The maximum value of the slider is now 60.

Slider Custom Colors

v-slider comes with props that allow us to modify the colors of its various elements.

Use the color prop to change the color of the part of the track before the thumb:

<template>
  <v-app>
    <div class="d-flex justify-center mt-2">
      <v-col sm="6">
        <v-slider label="color" v-model="sliderValue" color="green"></v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    sliderValue: 0,
  }),
};
</script>
Changing the color of the part of the track before the slider thumb.

The track-color prop will modify the color of the part of the track after the thumb:

<template>
  <v-app>
    <div class="d-flex justify-center mt-2">
      <v-col sm="6">
        <v-slider
          label="track-color"
          v-model="sliderValue"
          track-color="red"
        ></v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    sliderValue: 0,
  }),
};
</script>
Modifying the color of the part of the track after the slider thumb.

To change the color of the thumb, use the thumb-color prop:

<template>
  <v-app>
    <div class="d-flex justify-center mt-2">
      <v-col sm="6">
        <v-slider
          label="thumb-color"
          v-model="sliderValue"
          thumb-color="orange"
          thumb-label="always"
        ></v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    sliderValue: 0,
  }),
};
</script>
Changing the color of the slider thumb.

Disabled Sliders

Set the disabled prop to true to turn off interactivity with the slider:

<template>
  <v-app>
    <div class="d-flex justify-center mt-2">
      <v-col sm="6">
        <v-slider disabled value="50" label="Disabled"></v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
A disabled slider.

Discrete Sliders

By default Vuetify sliders have a step value of 1. These type of sliders are called continuous sliders because the thumb moves smoothly from its min to max value. In cases where we need less precision we can increase this step value, with the step prop:

<template>
  <v-app>
    <div class="d-flex justify-center mt-10">
      <v-col sm="6">
        <v-slider
          v-model="sliderValue"
          step="10"
          thumb-label="always"
        ></v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    sliderValue: 0,
  }),
};
</script>
A discrete slider.

Slider Icons

v-slider provides props to display icons along with the slider, useful for adding more context.

The prepend-icon prop will display the accompanying icon before the slider:

<template>
  <v-app>
    <div class="d-flex justify-center mt-2">
      <v-col sm="6">
        <v-slider v-model="volume" prepend-icon="mdi-volume-high"></v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    volume: 0,
  }),
};
</script>
Displaying an icon before a slider with the prepend-icon prop.

The append-icon will show the icon after the slider:

<template>
  <v-app>
    <div class="d-flex justify-center mt-2">
      <v-col sm="6">
        <v-slider v-model="volume" append-icon="mdi-volume-high"></v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    volume: 0,
  }),
};
</script>
Displaying an icon after a slider with the append-icon prop.

Readonly Sliders

Readonly sliders also prevent interactivity like disable sliders, but they don’t lose their color:

<template>
  <v-app>
    <div class="d-flex justify-center mt-2">
      <v-col sm="6">
        <v-slider readonly value="30" label="Readonly"></v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
A readonly slider.

Inverse Labels

To display the slider label at the end of the slider, use the inverse-label prop:

<template>
  <v-app>
    <div class="d-flex justify-center mt-2">
      <v-col sm="6">
        <v-slider label="Inverse label" inverse-label></v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Display the label at the end of the slider with the inverse-label prop.

Slider Thumbs

v-slider offers certain props for customizing the behaviour and display of the thumb. Set the thumb-label prop to true to display to only display the thumb label when the slider is being used:

<template>
  <v-app>
    <div class="d-flex justify-center mt-10">
      <v-col sm="6">
        <v-slider v-model="value" label="Slider" thumb-label></v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 0,
  }),
};
</script>
The thumb displays only when the slider is being used.

To always show the thumb label whether the user is using the slider or not, set the thumb-label prop to always:

<template>
  <v-app>
    <div class="d-flex justify-center mt-10">
      <v-col sm="6">
        <v-slider v-model="value" label="Slider" thumb-label="always"></v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 0,
  }),
};
</script>
Making the slider thumb display all the time.

Custom Thumb Sizes

The thumb-size prop lets us modify the thumb size:

<template>
  <v-app>
    <div class="d-flex justify-center mt-16">
      <v-col sm="6">
        <v-slider
          v-model="value"
          label="Slider"
          thumb-label="always"
          thumb-size="50"
        ></v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 0,
  }),
};
</script>
Modifying the slider thumb size.

Custom Thumb Labels

The thumb normally displays the current numeric value of the slider, but we change what it shows by providing an element to the thumb-label slot of v-slider:

<template>
  <v-app>
    <div class="d-flex justify-center mt-16">
      <v-col sm="6">
        <v-slider
          v-model="value"
          label="Volume"
          thumb-label="always"
          thumb-size="50"
        >
          <template v-slot:thumb-label>
            <v-icon dark>mdi-volume-high</v-icon>
          </template>
        </v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 0,
  }),
};
</script>
A slider with a custom thumb label.

Slider Ticks

Ticks visually represent the values the user can move the slider to. Setting the ticks prop to true will show the slider only when the slider is being used:

<template>
  <v-app>
    <div class="d-flex justify-center mt-2">
      <v-col sm="6">
        <v-slider v-model="value" step="10" ticks> </v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 0,
  }),
};
</script>
The ticks display only when the slider is being used.

Set ticks to always to make the ticks display all the time:

<template>
  <v-app>
    <div class="d-flex justify-center mt-2">
      <v-col sm="6">
        <v-slider v-model="value" step="10" ticks="always"> </v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 0,
  }),
};
</script>
A slider with ticks that display all the time.

Custom Tick Sizes

We can also customize the tick size, with the tick-size prop:

<template>
  <v-app>
    <div class="d-flex justify-center mt-2">
      <v-col sm="6">
        <v-slider v-model="value" step="10" ticks="always" tick-size="4">
        </v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 0,
  }),
};
</script>
A slider with a custom tick size.

Tick Labels

We can add text to describe the ticks. To do this, set the tick-labels prop to an array of strings.

<template>
  <v-app>
    <div class="d-flex justify-center mt-2">
      <v-col sm="12">
        <v-slider
          v-model="value"
          step="10"
          ticks="always"
          :tick-labels="tickLabels"
        >
        </v-slider>
      </v-col>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 0,
    tickLabels: ['Terrible!', 'Bad', 'Okay', 'Good', 'Excellent!'],
  }),
};
</script>

Each item of the array will be assigned to a tick:

A slider with tick labels.

Summary

Vuetify provides the v-slider component to create sliders. We can use its props to customize various aspects of its behaviour and appearance.

Vuetify Margin and Padding: A Complete Guide

Space is a fundamental element of visual design and is important in every user interface. When building web apps, we usually space out elements from one another by modifying their paddings and margins. Vuetify provides spacing helper classes for adjusting the padding and margin of elements without having to create new classes. We’re going to learn how to use them in this post.

All the Vuetify helper classes are of the following format: {property}{direction}-{size}.

property

The property specifies the type of spacing to apply to the element. There are two possible values:

  • m – applies a margin.
  • p – applies padding.

direction

The direction indicates the margin or padding direction to apply the spacing. There are nine available directions in Vuetify:

  • t – applies the spacing for the margin-top or padding-top CSS properties of the element.
  • b – applies the spacing for margin-bottom or padding-bottom.
  • l – applies the spacing for margin-left or padding-left.
  • r – applies the spacing for margin-right or padding-right.
  • s – When Vuetify is in the default LTR mode, s acts similar to l. But in RTL mode, it behaves like r.
  • e – When Vuetify is in the default LTR mode, e acts similar to r. But in RTL mode, it behaves like l.
  • x – applies the spacing for both *-left and *-right.
  • y – applies the spacing for both *-top and *-bottom.
  • a – applies the spacing for the property in all four directions.
The specifiable directions for the Vuetify spacing helper classes.

size

The size sets the actual value of the spacing in pixels. A size 0 will remove the margin or padding from the element in the specified direction. To get the number of pixels for positive values, simply multiply the size number by 4px. Vuetify provides 16 possible positive spacing values:

  • 1 – sets the margin or padding to 4px.
  • 2 – sets the margin or padding to 8px.
  • 3 – sets the margin or padding to 12px.
  • 4 – sets the margin or padding to 16px.
  • 5 – sets the margin or padding to 20px.
  • 6 – sets the margin or padding to 24px.
  • 7 – sets the margin or padding to 28px.
  • 8 – sets the margin or padding to 32px.
  • 9 – sets the margin or padding to 36px.
  • 10 – sets the margin or padding to 40px.
  • 11 – sets the margin or padding to 44px.
  • 12 – sets the margin or padding to 48px.
  • 13 – sets the margin or padding to 52px.
  • 14 – sets the margin or padding to 56px.
  • 15 – sets the margin or padding to 60px.
  • 16 – sets the margin or padding to 64px.

We can specify negative spacing values by prefixing the number with an n. To get the number of pixels for negative values, multiply the size by -4px. Negative spacing values only apply to margins, and there are also 16 of them in Vuetify:

  • n1 – sets the margin to -4px.
  • n2 – sets the margin to -8px.
  • n3 – set the margin to -12px.
  • n4 – sets the margin to -16px.
  • n5 – sets the margin to -20px.
  • n6 – sets the margin to -24px.
  • n7 – sets the margin to -28px.
  • n8 – sets the margin to -32px.
  • n9 – sets the margin to -36px.
  • n10 – sets the margin to -40px.
  • n11 – sets the margin to -44px.
  • n12 – sets the margin to -48px.
  • n13 – sets the margin to -52px.
  • n14 – sets the margin to -56px.
  • n15 – sets the margin to -60px.
  • n16 – sets the margin to -64px.

Apart from the above available spacing values, we also have the auto spacing, which sets margins or paddings of elements to the auto value.

Examples

Now that we know the Vuetify spacing helper classes, let’s see how to use them in practice.

<template>
  <v-app>
    <v-row>
      <v-col sm="6"> <v-card color="blue" dark>JavaScript</v-card> </v-col>
      <v-col sm="6"> <v-card color="green" dark>PHP</v-card></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

Here we’ve created two cards and customized their colors:

Two cards with customized colors.

Let’s add the mt-2 class to the v-row element containing the cards:

<template>
  <v-app>
    <v-row class="mt-2">
      <v-col sm="6"> <v-card color="blue" dark>JavaScript</v-card> </v-col>
      <v-col sm="6"> <v-card color="green" dark>PHP</v-card></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

If you understood everything we covered previously, you’ll know that the mt-2 class will set the top margin of the v-row to 8px. When you run this code, you’ll see that there’s now some spacing between the two cards and the top of the page:

With the mx-3 class we’ll also create left and right margins (of 12px):

<template>
  <v-app>
    <v-row class="mt-2 mx-3">
      <v-col sm="6"> <v-card color="blue" dark>JavaScript</v-card> </v-col>
      <v-col sm="6"> <v-card color="green" dark>PHP</v-card></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using Vuetify margin helper classes to add left and right margins of 12px.

And then, we’ll use the pa-4 and pa-6 classes to add paddings of different sizes to the two cards:

<template>
  <v-app>
    <v-row class="mt-2 mx-3">
      <v-col sm="6">
        <v-card color="blue" dark class="pa-4">JavaScript</v-card>
      </v-col>
      <v-col sm="6">
        <v-card color="green" dark class="pa-6">PHP</v-card></v-col
      >
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Adding paddings of different sizes to the cards with a Vuetify padding helper class.

Here’s another example. We have two buttons, whose colors we’ve set to green and red:

<template>
  <v-app>
    <v-col>
      <v-btn color="green" dark>Okay</v-btn>
      <v-btn color="red" dark>Cancel</v-btn></v-col
    >
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Two green and red Vuetify buttons.

The py-10 class will add a bottom and top padding of 40px to the green button:

<template>
  <v-app>
    <v-col>
      <v-btn color="green" class="py-10" dark>Okay</v-btn>
      <v-btn color="red" dark>Cancel</v-btn></v-col
    >
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Adding padding to the green button with a Vuetify padding helper class.

To space out the buttons, we’ll add a left margin to the Cancel button with the ml-5 class:

<template>
  <v-app>
    <v-col>
      <v-btn color="green" class="py-10" dark>Okay</v-btn>
      <v-btn color="red" dark class="ml-5">Cancel</v-btn></v-col
    >
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Spacing out the buttons with a Vuetify margin helper class.

We’ll also pad it horizontally with the px-16 class:

<template>
  <v-app>
    <v-col>
      <v-btn color="green" class="py-10" dark>Okay</v-btn>
      <v-btn color="red" dark class="ml-5 px-16">Cancel</v-btn></v-col
    >
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Padding the "Cancel" button with the Vuetify padding helper class.

Let’s add a negative right margin to the Okay button to remove the spacing we added:

<template>
  <v-app>
    <v-col>
      <v-btn color="green" class="py-10 mr-n5" dark>Okay</v-btn>
      <v-btn color="red" dark class="ml-5 px-16">Cancel</v-btn></v-col
    >
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using a Vuetify negative margin helper class to remove the spacing between the buttons.

Conclusion

Vuetify provides spacing helper classes to allow us to space out and pad our UI elements without using custom classes or inline CSS. These classes can alter the margins or paddings of the elements in different directions and to various sizes.

Vuetify Select: How to Create Dropdown Lists with Vuetify

Dropdown lists are useful for getting user input from a known group of options, e.g., selecting a country among all the countries in the world, or choosing the hour of the day for an alarm. There are also known as select fields. In this article, we’re going to learn how use the Vuetify Select component to start creating dropdown lists in our apps.

The v-select Component

Vuetify provides the v-select component for creating select fields:

<template>
  <v-app>
    <v-row justify="center">
      <v-col sm="6"><v-select></v-select></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
A Vuetify select field.

Vuetify Select Field Labels

We can describe a dropdown list with the label prop of v-select. We are going to be display a list of colors, so let’s label it “Color”:

<template>
  <v-app>
    <v-row justify="center" class="ma-2">
      <v-col sm="6"><v-select label="Color"></v-select></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
A Vuetify select field with a label.

Vuetify Select Field Items

There are not options to select from in the dropdown list yet. Here’s what shows up when you click it:

No data available.

We can add items by assigning an array to the items prop. The items will be a group of colors.

<template>
  <v-app>
    <v-row justify="center" class="ma-2">
      <v-col sm="6"
        ><v-select label="Color" :items="items"></v-select
      ></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: ['Blue', 'Red', 'Yellow', 'Green'],
  }),
};
</script>

Now there are options in the dropdown list.

A dropdown list with options.

We can now choose one of the options:

Choosing one of the options from the dropdown list.

Vuetify Select Set Default Value

To set a default value for a dropdown list, we can use v-model to create a two-way binding between the current value of the dropdown list and a variable. The initial value of this variable will be the default value of the select field:

<template>
  <v-app>
    <v-row justify="center" class="ma-2">
      <v-col sm="6"
        ><v-select
          label="Color"
          :items="items"
          v-model="defaultSelection"
        ></v-select
      ></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    defaultSelection: 'Yellow',
    items: ['Blue', 'Red', 'Yellow', 'Green'],
  }),
};
</script>
Setting a default value for a Vuetify select field.

Vuetify Select Field Filled Variant

We can set an alternative filled variant for a select field with the filled prop:

<template>
  <v-app>
    <v-row justify="center" class="ma-2">
      <v-col sm="6"
        ><v-select label="Color" :items="items" filled></v-select
      ></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: ['Blue', 'Red', 'Yellow', 'Green'],
  }),
};
</script>
Vuetify select field field variant.

Vuetify Select Field Outlined Variant

We can also use an alternative outlined style, by setting the outlined prop of v-select to true:

<template>
  <v-app>
    <v-row justify="center" class="ma-2">
      <v-col sm="6"
        ><v-select label="Color" :items="items" outlined></v-select
      ></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: ['Blue', 'Red', 'Yellow', 'Green'],
  }),
};
</script>
Vuetify select outlined variant.

Vuetify Select Field Solo Variant

We can use the solo variant with the solo prop:

<template>
  <v-app>
    <v-row justify="center" class="ma-2">
      <v-col sm="6"
        ><v-select label="Color" :items="items" solo></v-select
      ></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: ['Blue', 'Red', 'Yellow', 'Green'],
  }),
};
</script>

Dense Select Fields

Setting the dense prop to true on a v-select will compact the dropdown list:

<template>
  <v-app>
    <v-row justify="center" class="ma-2">
      <v-col sm="6"
        ><v-select label="Color" :items="items" outlined dense></v-select
      ></v-col>
      <v-col sm="6"
        ><v-select label="Color" :items="items" solo dense></v-select
      ></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: ['Blue', 'Red', 'Yellow', 'Green'],
  }),
};
</script>
Dense dropdown lists.

Disabled Select Fields

To prevent interactivity with a select field, use the disabled prop:

<template>
  <v-app>
    <v-row justify="center" class="ma-2">
      <v-col sm="6"
        ><v-select label="Color" :items="items" disabled></v-select
      ></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: ['Blue', 'Red', 'Yellow', 'Green'],
  }),
};
</script>
A disabled Vuetify select field.

Select Field Icons

The prepend-icon prop allows us to prepend an icon to a dropdown list. Here we’re displaying a palette icon to represent color:

<template>
  <v-app>
    <v-row justify="center" class="ma-2">
      <v-col sm="6"
        ><v-select
          label="Color"
          :items="items"
          prepend-icon="mdi-palette"
        ></v-select
      ></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: ['Blue', 'Red', 'Yellow', 'Green'],
  }),
};
</script>
Using the v-select prepend-icon prop.

Similarly, we can use the append-icon prop to append an icon to a select field:

<template>
  <v-app>
    <v-row justify="center" class="ma-2">
      <v-col sm="6"
        ><v-select
          label="Color"
          :items="items"
          append-icon="mdi-palette"
        ></v-select
      ></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: ['Blue', 'Red', 'Yellow', 'Green'],
  }),
};
</script>
Using the v-select append-icon prop.

Multi Select Dropdown Lists in Vuetify

In instances where we want users to be able to select more than one option, we can use the multiple prop

<template>
  <v-app>
    <v-row justify="center" class="ma-2">
      <v-col sm="6"
        ><v-select
          label="Color"
          :items="items"

          multiple
        ></v-select
      ></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: ['Blue', 'Red', 'Yellow', 'Green'],
  }),
};
</script>
Selecting two options in a dropdown list.
Selecting two options in a dropdown list.
The dropdown list options are comma-separated.
The options are comma-separated.

Displaying Chips in Multi Select Dropdown Lists

We can display the options as a group of chips instead of comma-separated values. We do this with the chips prop:

<template>
  <v-app>
    <v-row justify="center" class="ma-2">
      <v-col sm="6"
        ><v-select
          label="Color"
          :items="items"

          multiple
          chips
        ></v-select
      ></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: ['Blue', 'Red', 'Yellow', 'Green'],
  }),
};
</script>
Displaying chips in multi select dropdown lists.

Customizing Select Field Menu Props

We can customize certain properties of the menu that pops up when the dropdown list is clicked. Modifiable properties include top, bottom, offsetX and offsetY.

<template>
  <v-app>
    <v-row justify="center" class="ma-2">
      <v-col sm="6"
        ><v-select
          label="Color"
          :items="items"
          :menu-props="{ offsetX: true }"
        ></v-select
      ></v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: ['Blue', 'Red', 'Yellow', 'Green'],
  }),
};
</script>
Customizing select field menu props.

Summary

Dropdown lists come in handy when we want to provide a finite list of known options to the user to choose from. Vuetify provides the v-select component to create and customize them in diverse ways.

Vuetify Data Table: How to Create Data Tables

A table is a great way of presenting structured information in an easily understandable format. In this post, we’re going to learn how to use the Vuetify data table component, which is used for displaying tabular data and comes with useful features such as sorting, searching, pagination, and more.

The Vuetify Data Table Component (v-data-table)

Vuetify provides the v-data-table component for creating data tables. The headers prop of this component is an array of objects used to configure the data table headers. Each object in this array has a text property, which determines the header name that shows up for a particular column. We also pass an array of objects (desserts) to the items prop. Each object in desserts corresponds to a row in the data table, and each property represents a table cell for that row. The property names of these objects have to match one of the value property values of the objects in the headers array, i.e. (a key name must be one of name, calories, fat, carbs, protein, and iron).

We use the items-per-page property to paginate the data table. Here we set it to 5, so we have 2 pages for the 10 desserts.

<template>
  <v-app>
    <v-data-table
      :headers="headers"
      :items="desserts"
      :items-per-page="5"
      class="elevation-1"
    ></v-data-table>
  </v-app>
</template>
<script>
export default {
  data() {
    return {
      headers: [
        {
          text: 'Dessert (100g serving)',
          align: 'start',
          sortable: false,
          value: 'name',
        },
        { text: 'Calories', value: 'calories' },
        { text: 'Fat (g)', value: 'fat' },
        { text: 'Carbs (g)', value: 'carbs' },
        { text: 'Protein (g)', value: 'protein' },
        { text: 'Iron (%)', value: 'iron' },
      ],
      desserts: [
        {
          name: 'Frozen Yogurt',
          calories: 159,
          fat: 6.0,
          carbs: 24,
          protein: 4.0,
          iron: '1%',
        },
        {
          name: 'Ice cream sandwich',
          calories: 237,
          fat: 9.0,
          carbs: 37,
          protein: 4.3,
          iron: '1%',
        },
        {
          name: 'Eclair',
          calories: 262,
          fat: 16.0,
          carbs: 23,
          protein: 6.0,
          iron: '7%',
        },
        {
          name: 'Cupcake',
          calories: 305,
          fat: 3.7,
          carbs: 67,
          protein: 4.3,
          iron: '8%',
        },
        {
          name: 'Gingerbread',
          calories: 356,
          fat: 16.0,
          carbs: 49,
          protein: 3.9,
          iron: '16%',
        },
        {
          name: 'Jelly bean',
          calories: 375,
          fat: 0.0,
          carbs: 94,
          protein: 0.0,
          iron: '0%',
        },
        {
          name: 'Lollipop',
          calories: 392,
          fat: 0.2,
          carbs: 98,
          protein: 0,
          iron: '2%',
        },
        {
          name: 'Honeycomb',
          calories: 408,
          fat: 3.2,
          carbs: 87,
          protein: 6.5,
          iron: '45%',
        },
        {
          name: 'Donut',
          calories: 452,
          fat: 25.0,
          carbs: 51,
          protein: 4.9,
          iron: '22%',
        },
        {
          name: 'KitKat',
          calories: 518,
          fat: 26.0,
          carbs: 65,
          protein: 7,
          iron: '6%',
        },
      ],
    };
  },
};
</script>

And here’s our table:

A Vuetify data table created with the v-data-table component.

Vuetify Data Table Dense

Setting the dense prop makes a data table more compact, as the name implies:

<template>
  <v-app>
    <v-data-table
      dense
      :headers="headers"
      :items="desserts"
      item-key="name"
      class="elevation-1"
    ></v-data-table>
  </v-app>
</template>
<script>
export default {
  data: () => ({
    desserts: [
      {
        name: 'Frozen Yogurt',
        calories: 159,
        fat: 6.0,
        carbs: 24,
        protein: 4.0,
        iron: '1%',
      },
      {
        name: 'Ice cream sandwich',
        calories: 237,
        fat: 9.0,
        carbs: 37,
        protein: 4.3,
        iron: '1%',
      },
      {
        name: 'Eclair',
        calories: 262,
        fat: 16.0,
        carbs: 23,
        protein: 6.0,
        iron: '7%',
      },
      {
        name: 'Cupcake',
        calories: 305,
        fat: 3.7,
        carbs: 67,
        protein: 4.3,
        iron: '8%',
      },
      {
        name: 'Gingerbread',
        calories: 356,
        fat: 16.0,
        carbs: 49,
        protein: 3.9,
        iron: '16%',
      },
      {
        name: 'Jelly bean',
        calories: 375,
        fat: 0.0,
        carbs: 94,
        protein: 0.0,
        iron: '0%',
      },
      {
        name: 'Lollipop',
        calories: 392,
        fat: 0.2,
        carbs: 98,
        protein: 0,
        iron: '2%',
      },
      {
        name: 'Honeycomb',
        calories: 408,
        fat: 3.2,
        carbs: 87,
        protein: 6.5,
        iron: '45%',
      },
      {
        name: 'Donut',
        calories: 452,
        fat: 25.0,
        carbs: 51,
        protein: 4.9,
        iron: '22%',
      },
      {
        name: 'KitKat',
        calories: 518,
        fat: 26.0,
        carbs: 65,
        protein: 7,
        iron: '6%',
      },
    ],
    headers: [
      {
        text: 'Dessert (100g serving)',
        align: 'start',
        sortable: false,
        value: 'name',
      },
      { text: 'Calories', value: 'calories' },
      { text: 'Fat (g)', value: 'fat' },
      { text: 'Carbs (g)', value: 'carbs' },
      { text: 'Protein (g)', value: 'protein' },
      { text: 'Iron (%)', value: 'iron' },
    ],
  }),
};
</script>
A dense Vuetify data table.

Vuetify Data Table Search Features

We can filter data on the data table with the search prop. Here, we’re binding whatever value entered in the text field with the input used for searching the table:

<template>
  <v-app>
    <v-card>
      <v-card-title>
        Nutrition
        <v-spacer></v-spacer>
        <v-text-field
          v-model="search"
          append-icon="mdi-magnify"
          label="Search"
          single-line
          hide-details
        ></v-text-field>
      </v-card-title>
      <v-data-table
        :headers="headers"
        :items="desserts"
        :search="search"
        :items-per-page="5"
      ></v-data-table>
    </v-card>
  </v-app>
</template>
<script>
export default {
  data: () => ({
    search: '',
    desserts: [
      {
        name: 'Frozen Yogurt',
        calories: 159,
        fat: 6.0,
        carbs: 24,
        protein: 4.0,
        iron: '1%',
      },
      {
        name: 'Ice cream sandwich',
        calories: 237,
        fat: 9.0,
        carbs: 37,
        protein: 4.3,
        iron: '1%',
      },
      {
        name: 'Eclair',
        calories: 262,
        fat: 16.0,
        carbs: 23,
        protein: 6.0,
        iron: '7%',
      },
      {
        name: 'Cupcake',
        calories: 305,
        fat: 3.7,
        carbs: 67,
        protein: 4.3,
        iron: '8%',
      },
      {
        name: 'Gingerbread',
        calories: 356,
        fat: 16.0,
        carbs: 49,
        protein: 3.9,
        iron: '16%',
      },
      {
        name: 'Jelly bean',
        calories: 375,
        fat: 0.0,
        carbs: 94,
        protein: 0.0,
        iron: '0%',
      },
      {
        name: 'Lollipop',
        calories: 392,
        fat: 0.2,
        carbs: 98,
        protein: 0,
        iron: '2%',
      },
      {
        name: 'Honeycomb',
        calories: 408,
        fat: 3.2,
        carbs: 87,
        protein: 6.5,
        iron: '45%',
      },
      {
        name: 'Donut',
        calories: 452,
        fat: 25.0,
        carbs: 51,
        protein: 4.9,
        iron: '22%',
      },
      {
        name: 'KitKat',
        calories: 518,
        fat: 26.0,
        carbs: 65,
        protein: 7,
        iron: '6%',
      },
    ],
    headers: [
      {
        text: 'Dessert (100g serving)',
        align: 'start',
        sortable: false,
        value: 'name',
      },
      { text: 'Calories', value: 'calories' },
      { text: 'Fat (g)', value: 'fat' },
      { text: 'Carbs (g)', value: 'carbs' },
      { text: 'Protein (g)', value: 'protein' },
      { text: 'Iron (%)', value: 'iron' },
    ],
  }),
};
</script>
Add search features to a Vuetify data table component.

Vuetify Data Table Custom Filters

We can specify our custom filter function by passing a method to the custom-filter prop that has the signature (value: any, search: string | null, item: any) => boolean.

<template>
  <v-app>
    <div>
      <v-data-table
        :headers="headers"
        :items="desserts"
        item-key="name"
        class="elevation-1"
        :search="search"
        :custom-filter="filterOnlyCapsText"
        :items-per-page="5"
      >
        <template v-slot:top>
          <v-text-field
            v-model="search"
            label="Search (UPPER CASE ONLY)"
            class="mx-4"
          ></v-text-field>
        </template>
      </v-data-table>
    </div>
  </v-app>
</template>
<script>
export default {
  name: 'App',
  data() {
    return {
      search: '',
      calories: '',
      desserts: [
        {
          name: 'Frozen Yogurt',
          calories: 159,
          fat: 6.0,
          carbs: 24,
          protein: 4.0,
          iron: '1%',
        },
        {
          name: 'Ice cream sandwich',
          calories: 237,
          fat: 9.0,
          carbs: 37,
          protein: 4.3,
          iron: '1%',
        },
        {
          name: 'Eclair',
          calories: 262,
          fat: 16.0,
          carbs: 23,
          protein: 6.0,
          iron: '7%',
        },
        {
          name: 'Cupcake',
          calories: 305,
          fat: 3.7,
          carbs: 67,
          protein: 4.3,
          iron: '8%',
        },
        {
          name: 'Gingerbread',
          calories: 356,
          fat: 16.0,
          carbs: 49,
          protein: 3.9,
          iron: '16%',
        },
        {
          name: 'Jelly bean',
          calories: 375,
          fat: 0.0,
          carbs: 94,
          protein: 0.0,
          iron: '0%',
        },
        {
          name: 'Lollipop',
          calories: 392,
          fat: 0.2,
          carbs: 98,
          protein: 0,
          iron: '2%',
        },
        {
          name: 'Honeycomb',
          calories: 408,
          fat: 3.2,
          carbs: 87,
          protein: 6.5,
          iron: '45%',
        },
        {
          name: 'Donut',
          calories: 452,
          fat: 25.0,
          carbs: 51,
          protein: 4.9,
          iron: '22%',
        },
        {
          name: 'KitKat',
          calories: 518,
          fat: 26.0,
          carbs: 65,
          protein: 7,
          iron: '6%',
        },
      ],
    };
  },
  computed: {
    headers() {
      return [
        {
          text: 'Dessert (100g serving)',
          align: 'start',
          sortable: false,
          value: 'name',
        },
        {
          text: 'Calories',
          value: 'calories',
        },
        { text: 'Fat (g)', value: 'fat' },
        { text: 'Carbs (g)', value: 'carbs' },
        { text: 'Protein (g)', value: 'protein' },
        { text: 'Iron (%)', value: 'iron' },
      ];
    },
  },
  methods: {
    filterOnlyCapsText(value, search, item) {
      return (
        value != null &&
        search != null &&
        typeof value === 'string' &&
        value.toString().toLocaleUpperCase().indexOf(search) !== -1
      );
    },
  },
};
</script>
Add custom filters with the custom-filter prop of the Vuetify data table component.

We can also customize the filtering of a specific column by supplying a function to the filter property on an item in the array passed to the headers prop. In the code example below, we add a text field below the rows of the data table (with the body.append slot) which can be used to display all the desserts with calories less than a certain value.

<template>
  <v-app>
    <div>
      <v-data-table
        :headers="headers"
        :items="desserts"
        item-key="name"
        class="elevation-1"
        :search="search"
        :custom-filter="filterOnlyCapsText"
        :items-per-page="5"
      >
        <template v-slot:top>
          <v-text-field
            v-model="search"
            label="Search (UPPER CASE ONLY)"
            class="mx-4"
          ></v-text-field>
        </template>
        <template v-slot:body.append>
          <tr>
            <td></td>
            <td>
              <v-text-field
                v-model="calories"
                type="number"
                label="Less than"
              ></v-text-field>
            </td>
            <td colspan="4"></td>
          </tr>
        </template>
      </v-data-table>
    </div>
  </v-app>
</template>
<script>
export default {
  name: 'App',
  data() {
    return {
      search: '',
      calories: '',
      desserts: [
        {
          name: 'Frozen Yogurt',
          calories: 159,
          fat: 6.0,
          carbs: 24,
          protein: 4.0,
          iron: '1%',
        },
        {
          name: 'Ice cream sandwich',
          calories: 237,
          fat: 9.0,
          carbs: 37,
          protein: 4.3,
          iron: '1%',
        },
        {
          name: 'Eclair',
          calories: 262,
          fat: 16.0,
          carbs: 23,
          protein: 6.0,
          iron: '7%',
        },
        {
          name: 'Cupcake',
          calories: 305,
          fat: 3.7,
          carbs: 67,
          protein: 4.3,
          iron: '8%',
        },
        {
          name: 'Gingerbread',
          calories: 356,
          fat: 16.0,
          carbs: 49,
          protein: 3.9,
          iron: '16%',
        },
        {
          name: 'Jelly bean',
          calories: 375,
          fat: 0.0,
          carbs: 94,
          protein: 0.0,
          iron: '0%',
        },
        {
          name: 'Lollipop',
          calories: 392,
          fat: 0.2,
          carbs: 98,
          protein: 0,
          iron: '2%',
        },
        {
          name: 'Honeycomb',
          calories: 408,
          fat: 3.2,
          carbs: 87,
          protein: 6.5,
          iron: '45%',
        },
        {
          name: 'Donut',
          calories: 452,
          fat: 25.0,
          carbs: 51,
          protein: 4.9,
          iron: '22%',
        },
        {
          name: 'KitKat',
          calories: 518,
          fat: 26.0,
          carbs: 65,
          protein: 7,
          iron: '6%',
        },
      ],
    };
  },
  computed: {
    headers() {
      return [
        {
          text: 'Dessert (100g serving)',
          align: 'start',
          sortable: false,
          value: 'name',
        },
        {
          text: 'Calories',
          value: 'calories',
          filter: (value) => {
            return this.calories ? value < parseInt(this.calories) : true;
          },
        },
        { text: 'Fat (g)', value: 'fat' },
        { text: 'Carbs (g)', value: 'carbs' },
        { text: 'Protein (g)', value: 'protein' },
        { text: 'Iron (%)', value: 'iron' },
      ];
    },
  },
  methods: {
    filterOnlyCapsText(value, search, item) {
      return (
        value != null &&
        search != null &&
        typeof value === 'string' &&
        value.toString().toLocaleUpperCase().indexOf(search) !== -1
      );
    },
  },
};
</script>
Customizing the filtering of a specific column of the Vuetify data table component.

Vuetify Data Table Filterable

We can prevent specific columns from being included when searching through the table rows by setting the filterable property to false on the element of the array passed to headers that is associated with the column. In the code example below, we’ve turned off searching for the dessert name column:

<template>
  <v-app>
    <v-card class="ma-4">
      <v-card-title>
        <v-text-field
          v-model="search"
          append-icon="mdi-magnify"
          label="Search"
          single-line
          hide-details
        ></v-text-field>
      </v-card-title>
      <v-data-table
        :headers="headers"
        :items="desserts"
        :search="search"
        :items-per-page="5"
      ></v-data-table>
    </v-card>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      search: '',
      headers: [
        {
          text: 'Dessert (100g serving)',
          align: 'start',
          filterable: false,
          value: 'name',
        },
        { text: 'Calories', value: 'calories' },
        { text: 'Fat (g)', value: 'fat' },
        { text: 'Carbs (g)', value: 'carbs' },
        { text: 'Protein (g)', value: 'protein' },
        { text: 'Iron (%)', value: 'iron' },
      ],
      desserts: [
        {
          name: 'Frozen Yogurt',
          calories: 159,
          fat: 6.0,
          carbs: 24,
          protein: 4.0,
          iron: '1%',
        },
        {
          name: 'Ice cream sandwich',
          calories: 237,
          fat: 9.0,
          carbs: 37,
          protein: 4.3,
          iron: '1%',
        },
        {
          name: 'Eclair',
          calories: 262,
          fat: 16.0,
          carbs: 23,
          protein: 6.0,
          iron: '7%',
        },
        {
          name: 'Cupcake',
          calories: 305,
          fat: 3.7,
          carbs: 67,
          protein: 4.3,
          iron: '8%',
        },
        {
          name: 'Gingerbread',
          calories: 356,
          fat: 16.0,
          carbs: 49,
          protein: 3.9,
          iron: '16%',
        },
        {
          name: 'Jelly bean',
          calories: 375,
          fat: 0.0,
          carbs: 94,
          protein: 0.0,
          iron: '0%',
        },
        {
          name: 'Lollipop',
          calories: 392,
          fat: 0.2,
          carbs: 98,
          protein: 0,
          iron: '2%',
        },
        {
          name: 'Honeycomb',
          calories: 408,
          fat: 3.2,
          carbs: 87,
          protein: 6.5,
          iron: '45%',
        },
        {
          name: 'Donut',
          calories: 452,
          fat: 25.0,
          carbs: 51,
          protein: 4.9,
          iron: '22%',
        },
        {
          name: 'KitKat',
          calories: 518,
          fat: 26.0,
          carbs: 65,
          protein: 7,
          iron: '6%',
        },
      ],
    };
  },
};
</script>
Using the filterable prop of the Vuetify data table component.

By default, the data table component displays a default footer using the v-data-footer component. We can pass props to this component with the footer-props prop of v-data-table:

<template>
  <v-app>
    <v-data-table
      :headers="headers"
      :items="desserts"
      :items-per-page="5"
      item-key="name"
      class="elevation-1 ma-4"
      :footer-props="{
        showFirstLastPage: true,
        firstIcon: 'mdi-arrow-collapse-left',
        lastIcon: 'mdi-arrow-collapse-right',
        prevIcon: 'mdi-minus',
        nextIcon: 'mdi-plus',
      }"
    ></v-data-table>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      headers: [
        {
          text: 'Dessert (100g serving)',
          align: 'start',
          value: 'name',
        },
        { text: 'Category', value: 'category' },
      ],
      desserts: [
        {
          name: 'Frozen Yogurt',
          category: 'Ice cream',
        },
        {
          name: 'Ice cream sandwich',
          category: 'Ice cream',
        },
        {
          name: 'Eclair',
          category: 'Cookie',
        },
        {
          name: 'Cupcake',
          category: 'Pastry',
        },
        {
          name: 'Gingerbread',
          category: 'Cookie',
        },
        {
          name: 'Jelly bean',
          category: 'Candy',
        },
        {
          name: 'Lollipop',
          category: 'Candy',
        },
        {
          name: 'Honeycomb',
          category: 'Toffee',
        },
        {
          name: 'Donut',
          category: 'Pastry',
        },
        {
          name: 'KitKat',
          category: 'Candy',
        },
      ],
    };
  },
};
</script>
Customizing the v-data-table footer with the footer-props prop.

Conclusion

The Vuetify data table component (v-data-table) comes in handy for laying out data in a digestible format. We can not only display data but perform searching and other operations. It also allows UI customizations like making the table more compact and functional customizations such as specifying a custom filter function.

How to Use the Vuetify Checkbox Component

A checkbox allows a user to select between two values. They are useful for getting boolean input (true or false), perhaps checking off a task in a to-do list app to show completion or deciding whether or not to accept a license agreement during software installation. In this article, we’re going to learn how to create a checkbox in Vuetify.

The v-checkbox Component

Vuetify provides the v-checkbox component for creating a checkbox:

<template>
  <v-app>
    <v-row class="ma-2" justify="center">
      <v-checkbox></v-checkbox>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Creating a Vuetify checkbox with the v-checkbox component.

Clicking the checkbox will toggle its checked state:

Clicking the checkbox will toggle its value.

Setting a Checkbox value

Use the value prop to set the checked state of the checkbox.

<template>
  <v-app>
    <v-row class="ma-2" justify="center">
      <v-checkbox :value="true"></v-checkbox>
      <v-checkbox :value="false"></v-checkbox>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting a checkbox value.

Vuetify Checkbox Labels

We can label a Vuetify checkbox with the label prop:

<template>
  <v-app>
    <v-row class="ma-2" justify="center">
      <v-checkbox v-model="checked" label="Coding Beauty"></v-checkbox>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    checked: false,
  }),
};
</script>
Setting a label for a Vuetify checkbox.

Vuetify Checkbox Label Slot

To include HTML content in a checkbox label, we can put it in the label slot:

<template>
  <v-app>
    <v-row class="ma-2" justify="space-around">
      <v-checkbox color="indigo" input-value="true">
        <template v-slot:label>
          Visit the&nbsp;
          <a
            target="_blank"
            href="https://codingbeautydev.com"
            @click.stop
            v-on="on"
          >
            Coding Beauty website
          </a>
        </template>
      </v-checkbox>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Including HTML content in a Vuetify checkbox with the label slot.

Vuetify Checkbox Boolean v-model

To control the current value of the checkbox, we can use v-model to create a two-way binding between the v-checkbox and a boolean variable.

Here, we create a checkbox and a button below it to toggle the state of the checkbox. We indicate this state with some text in the label prop.

<template>
  <v-app>
    <div class="ma-2 d-flex justify-center">
      <v-checkbox v-model="checked" :label="`Checked: ${checked}`"></v-checkbox>
    </div>
    <div class="ma-2 d-flex justify-center">
      <v-btn color="indigo" dark @click="checked = !checked">{{
        checked ? 'Uncheck' : 'Check'
      }}</v-btn>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    checked: false,
  }),
};
</script>

Clicking the button will negate checked, and this will reflect on the checkbox and its label:

Using a boolean v-model on the Vuetify checkbox component.

Vuetify Checkbox Array v-model

We can pass an array to v-model to allow multiple checkbox components to share the same variable used for the two-way binding:

<template>
  <v-app>
    <v-container fluid>
      <p>Selected: {{ selected }}</p>
      <v-checkbox
        v-model="selected"
        label="JavaScript"
        value="javascript"
      ></v-checkbox>
      <v-checkbox
        v-model="selected"
        label="TypeScript"
        value="typescript"
      ></v-checkbox>
    </v-container>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    selected: [],
  }),
};
</script>
Padding an array v-model to the checkbox components.

Customizing Checkbox Color in Vuetify

The color prop allows us to set the color of the checkbox background when checked:

<template>
  <v-app>
    <v-row justify="space-around" class="ma-4">
      <v-checkbox color="primary" label="primary"></v-checkbox>
      <v-checkbox color="green" label="green"></v-checkbox>
      <v-checkbox color="yellow darken-3" label="yellow darken-3"></v-checkbox>
      <v-checkbox color="red" label="red"></v-checkbox>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Customizing checkbox color in Vuetify.

Disabled Checkbox

We can turn off checkbox interactivity with the disabled prop. It will no longer accept input when disabled.

<template>
  <v-app>
    <v-row class="ma-2" justify="space-around">
      <v-checkbox
        label="on disabled"
        color="green"
        input-value="true"
        disabled
      ></v-checkbox>
      <v-checkbox
        label="off disabled"
        color="green"
        disabled
      ></v-checkbox>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Disabled Vuetify checkboxes.

Indeterminate Checkbox

We can make the checkbox indeterminate by using the indeterminate prop on the v-checkbox:

<template>
  <v-app>
    <v-row class="ma-2" justify="space-around">
      <v-checkbox label="indeterminate" color="red" indeterminate></v-checkbox>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
An indeterminate Vuetify checkbox.

Summary

We can use a checkbox when we need to accept boolean input. Vuetify provides the v-checkbox component to create it and provides various props for customization.

Vuetify List: How to Create Lists with Vuetify

Lists are used to display a group of related information. This information might be dynamic and modifiable by the user (e.g., a list of contacts or tasks) or it might be static (like a list of links for navigating around an app). Lists provide a consistent styling for a group of text or images. In this article, we’re going to learn how to add lists to our UI using the Vuetify list component.

The v-list Component

The names of the components for creating lists in Vuetify are quite self-explanatory. The v-list component is for creating lists. We use the v-list-item component to create an additional item in the list. v-list-item-content contains the primary list content, and v-list-item-title displays the list title. For example:

<template>
  <v-app>
    <v-card class="mx-auto ma-4">
      <v-list>
        <v-list-item
          v-for="i in 5"
          :key="i"
        >
          <v-list-item-content>
            <v-list-item-title>
              List Item {{ i }}
            </v-list-item-title>
          </v-list-item-content>
        </v-list-item>
      </v-list>
    </v-card>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the Vuetify list component.

Vuetify List Two Line

Vuetify lists are single-line by default. To display two lines of content in a list, we set the two-line prop to true:

<template>
  <v-app>
    <v-card class="mx-auto ma-4">
      <v-list>
        <v-list-item
          v-for="i in 5"
          :key="i"
          two-line
        >
          <v-list-item-content>
            <v-list-item-title>
              List Item
            </v-list-item-title>
            <v-list-item-subtitle>
              Subtitle
            </v-list-item-subtitle>
          </v-list-item-content>
        </v-list-item>
      </v-list>
    </v-card>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the two-line prop of the Vuetify list component.

Vuetify List Three Line

We can also display three lines of text in a list with the three-line prop:

<template>
  <v-app>
    <v-card class="mx-auto ma-4">
      <v-list>
        <v-list-item
          v-for="i in 5"
          :key="i"
          three-line
        >
          <v-list-item-content>
            <v-list-item-title>
              List Item
            </v-list-item-title>
            <v-list-item-subtitle>
              Subtitle 1
            </v-list-item-subtitle>
            <v-list-item-subtitle>
              Subtitle 2
            </v-list-item-subtitle>
          </v-list-item-content>
        </v-list-item>
      </v-list>
    </v-card>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the three-line prop of the Vuetify list component.

Vuetify List Item Groups

We can use the v-list-item-group component in a list to create a group of selectable list items.

<template>
  <v-app>
    <v-card class="mx-auto ma-4" width="300">
      <v-list>
        <v-list-item-group v-model="selectedItem" color="primary">
          <v-list-item v-for="(item, i) in items" :key="i">
            <v-list-item-icon
              ><v-icon v-text="item.icon"></v-icon
            ></v-list-item-icon>
            <v-list-item-content>
              <v-list-item-title v-text="item.text"></v-list-item-title>
            </v-list-item-content>
          </v-list-item>
        </v-list-item-group>
      </v-list>
    </v-card>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    selectedItem: 1,
    items: [
      { text: 'Contacts', icon: 'mdi-account' },
      { text: 'Recent', icon: 'mdi-clock' },
      { text: 'Starred', icon: 'mdi-star' },
      { text: 'Settings', icon: 'mdi-cog' },
    ],
  }),
};
</script>
A selectable Vuetify list created with the list item group component.

The list maintains state, and clicking another list item will change the selection:

Changing the selected item of the list.

Dense Lists

We can compact lists in Vuetify with the dense prop:

<template>
  <v-app>
    <v-card class="mx-auto ma-4" width="300">
      <v-list dense>
        <v-list-item-group v-model="selectedItem" color="primary">
          <v-list-item v-for="(item, i) in items" :key="i">
            <v-list-item-icon
              ><v-icon v-text="item.icon"></v-icon
            ></v-list-item-icon>
            <v-list-item-content>
              <v-list-item-title v-text="item.text"></v-list-item-title>
            </v-list-item-content>
          </v-list-item>
        </v-list-item-group>
      </v-list>
    </v-card>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    selectedItem: 1,
    items: [
      { text: 'Contacts', icon: 'mdi-account' },
      { text: 'Recent', icon: 'mdi-clock' },
      { text: 'Starred', icon: 'mdi-star' },
      { text: 'Settings', icon: 'mdi-cog' },
    ],
  }),
};
</script>
Using the dense prop.

Disabled Lists

We can disable interaction with a list by setting the disabled prop to true:

<template>
  <v-app>
    <v-card class="mx-auto ma-4" width="300">
      <v-list disabled>
        <v-list-item-group v-model="selectedItem" color="primary">
          <v-list-item v-for="(item, i) in items" :key="i">
            <v-list-item-icon
              ><v-icon v-text="item.icon"></v-icon
            ></v-list-item-icon>
            <v-list-item-content>
              <v-list-item-title v-text="item.text"></v-list-item-title>
            </v-list-item-content>
          </v-list-item>
        </v-list-item-group>
      </v-list>
    </v-card>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    selectedItem: 1,
    items: [
      { text: 'Contacts', icon: 'mdi-account' },
      { text: 'Recent', icon: 'mdi-clock' },
      { text: 'Starred', icon: 'mdi-star' },
      { text: 'Settings', icon: 'mdi-cog' },
    ],
  }),
};
</script>

Flat Lists

The flat prop removes the background color of the selected list item:

<template>
  <v-app>
    <v-card class="mx-auto ma-4" width="300">
      <v-list flat>
        <v-list-item-group v-model="selectedItem" color="primary">
          <v-list-item v-for="(item, i) in items" :key="i">
            <v-list-item-icon
              ><v-icon v-text="item.icon"></v-icon
            ></v-list-item-icon>
            <v-list-item-content>
              <v-list-item-title v-text="item.text"></v-list-item-title>
            </v-list-item-content>
          </v-list-item>
        </v-list-item-group>
      </v-list>
    </v-card>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    selectedItem: 1,
    items: [
      { text: 'Contacts', icon: 'mdi-account' },
      { text: 'Recent', icon: 'mdi-clock' },
      { text: 'Starred', icon: 'mdi-star' },
      { text: 'Settings', icon: 'mdi-cog' },
    ],
  }),
};
</script>
A flat Vuetify list.

Vuetify List Nav Styling

Setting the nav prop to true on a v-list reduces the width and rounds the corners of the v-list-items in it:

<template>
  <v-app>
    <v-card class="mx-auto ma-4" width="300">
      <v-list nav>
        <v-list-item-group v-model="selectedItem" color="green">
          <v-list-item v-for="(item, i) in items" :key="i">
            <v-list-item-icon
              ><v-icon v-text="item.icon"></v-icon
            ></v-list-item-icon>
            <v-list-item-content>
              <v-list-item-title v-text="item.text"></v-list-item-title>
            </v-list-item-content>
          </v-list-item>
        </v-list-item-group>
      </v-list>
    </v-card>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    selectedItem: 1,
    items: [
      { text: 'Contacts', icon: 'mdi-account' },
      { text: 'Recent', icon: 'mdi-clock' },
      { text: 'Starred', icon: 'mdi-star' },
      { text: 'Settings', icon: 'mdi-cog' },
    ],
  }),
};
</script>
A Vuetify list with the nav styling.

Rounded List Items in Vuetify

We can make the v-list-items inside a v-list fully rounded by setting the rounded prop to true:

<template>
  <v-app>
    <v-card class="mx-auto ma-4" width="300">
      <v-list rounded>
        <v-list-item-group v-model="selectedItem" color="indigo">
          <v-list-item v-for="(item, i) in items" :key="i">
            <v-list-item-icon
              ><v-icon v-text="item.icon"></v-icon
            ></v-list-item-icon>
            <v-list-item-content>
              <v-list-item-title v-text="item.text"></v-list-item-title>
            </v-list-item-content>
          </v-list-item>
        </v-list-item-group>
      </v-list>
    </v-card>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    selectedItem: 1,
    items: [
      { text: 'Contacts', icon: 'mdi-account' },
      { text: 'Recent', icon: 'mdi-clock' },
      { text: 'Starred', icon: 'mdi-star' },
      { text: 'Settings', icon: 'mdi-cog' },
    ],
  }),
};
</script>
A Vuetify list with rounded list items.

Shaped List Items in Vuetify

Lists with the shaped prop set to true have rounded borders on one side of the v-list-items:

<template>
  <v-app>
    <v-card class="mx-auto ma-4" width="300">
      <v-list shaped>
        <v-list-item-group v-model="selectedItem" color="red accent-2">
          <v-list-item v-for="(item, i) in items" :key="i">
            <v-list-item-icon
              ><v-icon v-text="item.icon"></v-icon
            ></v-list-item-icon>
            <v-list-item-content>
              <v-list-item-title v-text="item.text"></v-list-item-title>
            </v-list-item-content>
          </v-list-item>
        </v-list-item-group>
      </v-list>
    </v-card>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    selectedItem: 1,
    items: [
      { text: 'Contacts', icon: 'mdi-account' },
      { text: 'Recent', icon: 'mdi-clock' },
      { text: 'Starred', icon: 'mdi-star' },
      { text: 'Settings', icon: 'mdi-cog' },
    ],
  }),
};
</script>
A Vuetify list with shaped list items.

Vuetify List Sub Groups

With the v-list-group component and its sub-group prop we can create sub groups of up to two levels in depth:

<template>
  <v-app>
    <v-card class="mx-auto ma-4" width="300">
      <v-list>
        <v-list-group :value="true" prepend-icon="mdi-file">
          <template v-slot:activator>
            <v-list-item-title>Files</v-list-item-title>
          </template>
          <v-list-group :value="true" no-action sub-group>
            <template v-slot:activator>
              <v-list-item-content>Books</v-list-item-content>
            </template>

            <v-list-item v-for="(book, i) in books" :key="i" link>
              <v-list-item-title v-text="book"></v-list-item-title>
              <v-list-item-icon><v-icon>mdi-book</v-icon></v-list-item-icon>
            </v-list-item>
          </v-list-group>
          <v-list-group no-action sub-group>
            <template v-slot:activator>
              <v-list-item-content>Code</v-list-item-content>
            </template>

            <v-list-item v-for="(code, i) in codes" :key="i" link>
              <v-list-item-title v-text="code"></v-list-item-title>
              <v-list-item-icon><v-icon>mdi-xml</v-icon></v-list-item-icon>
            </v-list-item>
          </v-list-group>
        </v-list-group>
        <v-list-item>
          <v-list-item-icon><v-icon>mdi-cog</v-icon></v-list-item-icon>
          <v-list-item-title>Settings</v-list-item-title>
        </v-list-item>
      </v-list>
    </v-card>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    selectedItem: 1,
    books: ['History', 'Fiction', 'Philosophy'],
    codes: ['C#', 'JavaScript', 'PHP'],
  }),
};
</script>
A Vuetify list with sub groups.

We can expand and contract the sub groups as needed:

Expanding and contracting sub groups in the list.

Summary

Lists are used to present a group of information that are related in some way. Vuetify provides v-list, v-list-group, v-list-item and other components for creating and customizing lists.

How to Use the Vuetify Icon Component

Icons are useful for conveying information to the user in a concise manner. They add more context to various aspects of our web apps. In this article, we’ll learn how to show icons in our apps to users with the Material Design framework.

The v-icon Component

Vuetify provides the v-icon component for displaying icons. This component provides a large set of glyphs. The list of all available icons is at the official Material Design Icons page. To use an icon in this list, we simply use the mdi- prefix followed by the icon name.

<template>
  <v-app>
    <v-col class="ma-2">
      <v-row justify="space-around">
        <v-icon>mdi-cog</v-icon>
        <v-icon> mdi-calendar</v-icon>
        <v-icon> mdi-access-point </v-icon>
        <v-icon> mdi-star </v-icon>
      </v-row>
    </v-col>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Displaying icons with the Vuetify icon component.

Customizing Icon Sizes in Vuetify

With the x-small, small, medium, large and x-large props, we can customize the icon sizes:

<template>
  <v-app>
    <v-col class="ma-2">
      <v-row justify="space-around">
        <v-icon> mdi-cog</v-icon>
        <v-icon> mdi-calendar</v-icon>
        <v-icon> mdi-access-point </v-icon>
        <v-icon> mdi-star </v-icon>
      </v-row>
      <v-row justify="space-around">
        <v-icon large> mdi-cog</v-icon>
        <v-icon large> mdi-calendar</v-icon>
        <v-icon large> mdi-access-point </v-icon>
        <v-icon large> mdi-star </v-icon>
      </v-row>
      <v-row justify="space-around">
        <v-icon x-large> mdi-cog</v-icon>
        <v-icon x-large> mdi-calendar</v-icon>
        <v-icon x-large> mdi-access-point </v-icon>
        <v-icon x-large> mdi-star </v-icon>
      </v-row>
    </v-col>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Displaying icons of various sizes.

Customizing Icon Colors in Vuetify

We can change the color of icons in Vuetify from the standard light and dark themes using the color prop:

<template>
  <v-app>
    <v-col class="ma-2">
      <v-row justify="space-around">
        <v-icon color="black">mdi-cog</v-icon>
        <v-icon color="primary"> mdi-calendar</v-icon>
        <v-icon color="red"> mdi-heart </v-icon>
        <v-icon color="yellow"> mdi-star </v-icon>
      </v-row>
    </v-col>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Customizing icon colors in Vuetify.

Icon Click Events in Vuetify

We can bind click events to the icon component to enable interactivity. For example:

<template>
  <v-app>
    <v-col class="ma-2">
      <v-row justify="center">
        <v-icon :color="liked ? 'red' : 'grey'" @click="liked = !liked">
          mdi-heart
        </v-icon>
      </v-row>
    </v-col>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    liked: false,
  }),
};
</script>
The heart icon, yet to be clicked.

When the user selects the heart icon, the color changes:

The heart icon becomes red after getting clicked

Placing Icons in Buttons

We can use icons inside of buttons to add more visual emphasis to the action the button performs:

<template>
  <v-app>
    <div class="ma-2 d-flex justify-space-around">
      <v-btn color="green" dark>
        Accept <v-icon right>mdi-checkbox-marked-circle</v-icon>
      </v-btn>
      <v-btn color="red" dark>
        Decline <v-icon right>mdi-cancel</v-icon>
      </v-btn>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    liked: false,
  }),
};
</script>
Placing icons inside of buttons.

Displaying Font Awesome Icons

Vuetify supports icons from Font Awesome. After including the Font Awesome icons in your project, you can show an icon with its fa- prefixed icon name:

<template>
  <v-app>
    <v-row align="start" justify="space-around" class="ma-4">
      <v-icon>fas fa-lock</v-icon>
      <v-icon>fas fa-search</v-icon>
      <v-icon>fas fa-list</v-icon>
      <v-icon>fas fa-edit</v-icon>
      <v-icon>fas fa-tachometer-alt</v-icon>
      <v-icon>fas fa-circle-notch</v-icon>
    </v-row>
  </v-app>
</template>


<script>
export default {
  name: 'App',
};
</script>
Displaying Font Awesome icons.

Displaying Material Design Icons

Vuetify also supports Material Design icons from material.io. We simply use the icon name inside the v-icon:

<template>
  <v-app>
    <v-row align="start" justify="space-around" class="ma-4">
      <v-icon>settings</v-icon>
      <v-icon>home</v-icon>
      <v-icon>search</v-icon>
      <v-icon>delete</v-icon>
      <v-icon>list</v-icon>
    </v-row>
  </v-app>
</template>


<script>
export default {
  name: 'App',
};
</script>
Displaying Material Design icons.

Summary

Icons are important UI elements used to concisely communicate and emphasize information to users. Vuetify provides the v-icon component for displaying icons. This component comes with various props for customization and supports Font Awesome and Material Design icons.

How to Use the Vuetify Navigation Drawer Component

Navigation drawers are useful for navigating through a web application. They provide an easily accessible means of quickly jumping from one location to another. In this article, we’ll learn how we can create and customize navigation drawers with Vuetify.

The v-navigation-drawer Component

We create navigation drawers in Vuetify with the v-navigation-drawer component. We set the app prop on this component to indicate to the Vuetify framework that it is part of the application layout.

<template>
  <v-app>
    <v-app-bar color="green" class="flex-grow-0" app dark>
      <v-app-bar-title>Coding Beauty</v-app-bar-title>
    </v-app-bar>
    <v-navigation-drawer app>
      <v-list-item>
        <v-list-item-content>
          <v-list-item-title class="text-h6"> Learning Vuetify </v-list-item-title>
          <v-list-item-subtitle> Navigation drawers</v-list-item-subtitle>
        </v-list-item-content>
      </v-list-item>
      <v-divider></v-divider>
      <v-list dense nav>
        <v-list-item v-for="item in items" :key="item.title" link>
          <v-list-item-icon>
            <v-icon>{{ item.icon }}</v-icon>
          </v-list-item-icon>

          <v-list-item-content>
            <v-list-item-title>{{ item.title }}</v-list-item-title>
          </v-list-item-content>
        </v-list-item>
      </v-list>
    </v-navigation-drawer>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: [
      { title: 'Dashboard', icon: 'mdi-view-dashboard' },
      { title: 'Account', icon: 'mdi-account-box' },
      { title: 'Settings', icon: 'mdi-cog' },
    ],
  }),
};
</script>
Creating Vuetify navigation drawers with the v-navigation-drawer component.

Temporary Navigation Drawers in Vuetify

Navigation drawers don’t have to be fixed. We can use a variable to toggle its visibility through v-model. We do this in the code below when the v-app-bar-nav-icon is selected. Apart from setting this variable to false, clicking outside of an open navigation drawer can also close it.

<template>
  <v-app>
    <v-app-bar color="primary" class="flex-grow-0" app dark>
      <v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
      <v-app-bar-title>Coding Beauty</v-app-bar-title>
    </v-app-bar>
    <v-navigation-drawer app v-model="drawer">
      <v-list-item>
        <v-list-item-content>
          <v-list-item-title class="text-h6"> Learning Vuetify</v-list-item-title>
          <v-list-item-subtitle> Using Navigation drawers</v-list-item-subtitle>
        </v-list-item-content>
      </v-list-item>
      <v-divider></v-divider>
      <v-list dense nav>
        <v-list-item v-for="item in items" :key="item.title" link>
          <v-list-item-icon>
            <v-icon>{{ item.icon }}</v-icon>
          </v-list-item-icon>

          <v-list-item-content>
            <v-list-item-title>{{ item.title }}</v-list-item-title>
          </v-list-item-content>
        </v-list-item>
      </v-list>
    </v-navigation-drawer>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    drawer: false,
    items: [
      { title: 'Dashboard', icon: 'mdi-view-dashboard' },
      { title: 'Account', icon: 'mdi-account-box' },
      { title: 'Settings', icon: 'mdi-cog' },
    ],
  }),
};
</script>
The navigation drawer is closed.
The navigation drawer is closed.
The navigation drawer is open.
Opening the navigation drawer.

Customizing Navigation Drawer Colors in Vuetify

We can use varying color styles on our navigation drawers with the color prop. With the dark prop, we can also make the text contained in the drawer light or dark, to blend in properly with its background color:

<template>
  <v-app>
    <v-app-bar color="primary" class="flex-grow-0" app dark>
      <v-app-bar-title>Coding Beauty</v-app-bar-title>
    </v-app-bar>
    <v-navigation-drawer app color="green" dark>
      <v-divider></v-divider>
      <v-list dense nav>
        <v-list-item v-for="item in items" :key="item.title" link>
          <v-list-item-icon>
            <v-icon>{{ item.icon }}</v-icon>
          </v-list-item-icon>

          <v-list-item-content>
            <v-list-item-title>{{ item.title }}</v-list-item-title>
          </v-list-item-content>
        </v-list-item>
      </v-list>
    </v-navigation-drawer>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: [
      { title: 'Dashboard', icon: 'mdi-view-dashboard' },
      { title: 'Account', icon: 'mdi-account-box' },
      { title: 'Settings', icon: 'mdi-cog' },
    ],
  }),
};
</script>
Navigation drawer custom colors.

Bottom Navigation Drawers in Vuetify

We can relocate the navigation drawer to come from the bottom of the screen on mobile devices, by setting the bottom prop to true. This alternative style only activates when its mobile-breakpoint is met.

<template>
  <v-app>
    <v-app-bar color="primary" class="flex-grow-0" app dark>
      <v-app-bar-nav-icon @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
      <v-app-bar-title>Coding Beauty</v-app-bar-title>
    </v-app-bar>
    <v-navigation-drawer app v-model="drawer" bottom>
      <v-list-item>
        <v-list-item-content>
          <v-list-item-title class="text-h6"> Learning Vuetify</v-list-item-title>
          <v-list-item-subtitle> Using Navigation drawers</v-list-item-subtitle>
        </v-list-item-content>
      </v-list-item>
      <v-divider></v-divider>
      <v-list dense nav>
        <v-list-item v-for="item in items" :key="item.title" link>
          <v-list-item-icon>
            <v-icon>{{ item.icon }}</v-icon>
          </v-list-item-icon>

          <v-list-item-content>
            <v-list-item-title>{{ item.title }}</v-list-item-title>
          </v-list-item-content>
        </v-list-item>
      </v-list>
    </v-navigation-drawer>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    drawer: false,
    items: [
      { title: 'Dashboard', icon: 'mdi-view-dashboard' },
      { title: 'Account', icon: 'mdi-account-box' },
      { title: 'Settings', icon: 'mdi-cog' },
    ],
  }),
};
</script>

Vuetify Navigation Drawer Mini Variant

With the mini-variant prop, we can reduce the size of the drawer and only show the first element of each of the elements inside the v-list. The drawer reduces to a size of 56px by default.

<template>
  <v-app>
    <v-app-bar color="primary" class="flex-grow-0" app dark>
      <v-app-bar-title>Coding Beauty</v-app-bar-title>
    </v-app-bar>
    <v-navigation-drawer app mini-variant>
      <v-divider></v-divider>
      <v-list dense nav>
        <v-list-item v-for="item in items" :key="item.title" link>
          <v-list-item-icon>
            <v-icon>{{ item.icon }}</v-icon>
          </v-list-item-icon>

          <v-list-item-content>
            <v-list-item-title>{{ item.title }}</v-list-item-title>
          </v-list-item-content>
        </v-list-item>
      </v-list>
    </v-navigation-drawer>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: [
      { title: 'Dashboard', icon: 'mdi-view-dashboard' },
      { title: 'Account', icon: 'mdi-account-box' },
      { title: 'Settings', icon: 'mdi-cog' },
    ],
  }),
};
</script>
Navigation drawer mini variant.

Expanding Navigation Drawers on Hover

If we want a navigation drawer of the mini-variant to expand on hover, we can set the expand-on-hover property to true:

<template>
  <v-app>
    <v-app-bar color="primary" class="flex-grow-0" app dark>
      <v-app-bar-title>Coding Beauty</v-app-bar-title>
    </v-app-bar>
    <v-navigation-drawer app expand-on-hover>
      <v-divider></v-divider>
      <v-list dense nav>
        <v-list-item v-for="item in items" :key="item.title" link>
          <v-list-item-icon>
            <v-icon>{{ item.icon }}</v-icon>
          </v-list-item-icon>

          <v-list-item-content>
            <v-list-item-title>{{ item.title }}</v-list-item-title>
          </v-list-item-content>
        </v-list-item>
      </v-list>
    </v-navigation-drawer>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: [
      { title: 'Dashboard', icon: 'mdi-view-dashboard' },
      { title: 'Account', icon: 'mdi-account-box' },
      { title: 'Settings', icon: 'mdi-cog' },
    ],
  }),
};
</script>
Navigation drawer expanding on mouse hover.
The navigation drawer expands on mouse hover.

Right-aligned Navigation Drawers in Vuetify

Setting the right prop to true on the navigation drawer component will align it to the right of the screen instead of the default left.

<template>
  <v-app>
    <v-app-bar color="red" class="flex-grow-0" app dark>
      <v-app-bar-title>Coding Beauty</v-app-bar-title>
    </v-app-bar>
    <v-navigation-drawer app right>
      <v-list-item>
        <v-list-item-content>
          <v-list-item-title class="text-h6"> Learning Vuetify </v-list-item-title>
          <v-list-item-subtitle> Navigation drawers</v-list-item-subtitle>
        </v-list-item-content>
      </v-list-item>
      <v-divider></v-divider>
      <v-list dense nav>
        <v-list-item v-for="item in items" :key="item.title" link>
          <v-list-item-icon>
            <v-icon>{{ item.icon }}</v-icon>
          </v-list-item-icon>

          <v-list-item-content>
            <v-list-item-title>{{ item.title }}</v-list-item-title>
          </v-list-item-content>
        </v-list-item>
      </v-list>
    </v-navigation-drawer>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: [
      { title: 'Dashboard', icon: 'mdi-view-dashboard' },
      { title: 'Account', icon: 'mdi-account-box' },
      { title: 'Settings', icon: 'mdi-cog' },
    ],
  }),
};
</script>
Aligning the navigation drawer to the right.

Permanent Navigation Drawers

By default, navigation drawers get hidden once its mobile-breakpoint is met:

The navigation drawer is hidden once its mobile-breakpoint is met.

We can prevent this using the permanent prop:

<template>
  <v-app>
    <v-app-bar color="indigo" class="flex-grow-0" app dark>
      <v-app-bar-title>Coding Beauty</v-app-bar-title>
    </v-app-bar>
    <v-card elevation="12">
      <v-navigation-drawer app permanent>
        <v-list-item>
          <v-list-item-content>
            <v-list-item-title class="text-h6">
              Learning Vuetify
            </v-list-item-title>
            <v-list-item-subtitle> Navigation drawers</v-list-item-subtitle>
          </v-list-item-content>
        </v-list-item>
        <v-divider></v-divider>
        <v-list dense nav>
          <v-list-item v-for="item in items" :key="item.title" link>
            <v-list-item-icon>
              <v-icon>{{ item.icon }}</v-icon>
            </v-list-item-icon>

            <v-list-item-content>
              <v-list-item-title>{{ item.title }}</v-list-item-title>
            </v-list-item-content>
          </v-list-item>
        </v-list>
      </v-navigation-drawer>
    </v-card>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    items: [
      { title: 'Dashboard', icon: 'mdi-view-dashboard' },
      { title: 'Account', icon: 'mdi-account-box' },
      { title: 'Settings', icon: 'mdi-cog' },
    ],
  }),
};
</script>

Using the permanent prop on the navigation drawer in Vuetify.

Summary

Similar to tabs, navigation drawers can be used to add an additional layer of navigation to your web applications. Vuetify provides the v-navigation-drawer component for creating them, with various props for customization.

Vuetify Toolbar: How to Create Beautiful Toolbars

A toolbar is a common way of allowing navigation across a web application. In this article, we’ll learn how to create and customize toolbars with the Vuetify toolbar component.

The Toolbar Component (v-toolbar)

Vuetify provides the v-toolbar component for creating a toolbar:

<template>
  <v-app>
    <v-toolbar class="flex-grow-0"> </v-toolbar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>

We use the flex-grow-0 flex helper on the toolbar to prevent it from covering half of the screen.

Creating a toolbar with the Vuetify toolbar component.

Vuetify Toolbar Title

We can use the v-toolbar-title component inside the v-toolbar to set the title of a toolbar. For example:

<template>
  <v-app>
    <v-toolbar class="flex-grow-0">
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
    </v-toolbar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting the title of the Vuetify toolbar component.

Vuetify Toolbar Colors

We can use the color prop of v-toolbar to customize the color of the toolbar.

<template>
  <v-app>
    <v-toolbar
      class="flex-grow-0"
      color="primary"
    >
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
    </v-toolbar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Customizing the color of the Vuetify toolbar component.

Vuetify Toolbar Dark

Apply the dark property to the toolbar component will make text on the toolbar white, instead of black. This can help to create a great color contrast between the text and the background.

<template>
  <v-app>
    <v-toolbar
      class="flex-grow-0"
      color="primary"
      dark
    >
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
    </v-toolbar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the dark prop of v-toolbar.

Vuetify Toolbar Actions

We can add functionality to a toolbar by placing buttons on it. In the example below, we add two icon buttons to the toolbar – one to search and another to display a menu containing more options.

<template>
  <v-app>
    <v-toolbar
      class="flex-grow-0"
      color="purple accent-4"
      dark
    >
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>

      <v-btn icon>
        <v-icon>mdi-dots-vertical</v-icon>
      </v-btn>
    </v-toolbar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Adding actions and functionality to the v-toolbar component.

Vuetify Toolbar Dense

Setting the dense prop to true on the v-toolbar component will make it more compact:

<template>
  <v-app>
    <v-toolbar
      class="flex-grow-0"
      color="white"
      dense
    >
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>

      <v-btn icon>
        <v-icon>mdi-heart</v-icon>
      </v-btn>

      <v-btn icon>
        <v-icon>mdi-dots-vertical</v-icon>
      </v-btn>
    </v-toolbar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the dense prop of the Vuetify toolbar component.

Vuetify Toolbar Flat

We can remove toolbar elevation with the flat property:

<template>
  <v-app>
    <v-toolbar
      class="flex-grow-0"
      color="red accent-2"
      dark
      flat
    >
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>

      <v-btn icon>
        <v-icon>mdi-heart</v-icon>
      </v-btn>

      <v-btn icon>
        <v-icon>mdi-dots-vertical</v-icon>
      </v-btn>
    </v-toolbar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the flat prop of v-toolbar.

Vuetify Toolbar Outlined

The outlined prop adds an outline around the toolbar.

<template>
  <v-app>
    <v-toolbar
      class="flex-grow-0"
      flat
      outlined
    >
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>

      <v-btn icon>
        <v-icon>mdi-heart</v-icon>
      </v-btn>

      <v-btn icon>
        <v-icon>mdi-dots-vertical</v-icon>
      </v-btn>
    </v-toolbar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the outlined prop of the Vuetify toolbar component.

Prominent Toolbar

With the prominent prop, we can create a toolbar with an increased height of 128px. A prominent toolbar has its title positioned towards the bottom of its container.

<template>
  <v-app>
    <v-toolbar
      class="flex-grow-0"
      dark
      color="green"
      prominent
    >
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>

      <v-btn icon>
        <v-icon>mdi-heart</v-icon>
      </v-btn>

      <v-btn icon>
        <v-icon>mdi-dots-vertical</v-icon>
      </v-btn>
    </v-toolbar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the prominent prop of v-toolbar.

Vuetify Toolbar Rounded

Setting the rounded prop to true on v-toolbar will add make the corners of the toolbar rounded

<template>
  <v-app>
    <v-toolbar
      class="flex-grow-0"
      dark
      color="green"
      rounded
    >
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>

      <v-btn icon>
        <v-icon>mdi-heart</v-icon>
      </v-btn>

      <v-btn icon>
        <v-icon>mdi-dots-vertical</v-icon>
      </v-btn>
    </v-toolbar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the rounded prop of v-toolbar.

Vuetify Toolbar Shaped

We can use the shaped prop to create a toolbar with the top-left and bottom-right corners rounded.

<template>
  <v-app>
    <v-toolbar
      class="flex-grow-0"
      dark
      color="indigo"
      shaped
    >
      <v-toolbar-title>Coding Beauty</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>

      <v-btn icon>
        <v-icon>mdi-heart</v-icon>
      </v-btn>

      <v-btn icon>
        <v-icon>mdi-dots-vertical</v-icon>
      </v-btn>
    </v-toolbar>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the shaped prop of the Vuetify toolbar component.

Conclusion

A toolbar is a user interface element used for site and app navigation. We can use the Vuetify toolbar component (v-toolbar) and its various props to create and customize toolbars.

How to Use the Vuetify Toggle Button Component

Toggle buttons are useful for creating a group of buttons whose individual selection states all depend on a single variable. In this article, we’ll see the ways in which we can create and customize this component in Vuetify.

The v-btn-toggle Component

We can create a button group (or toggle button) in Vuetify with the v-btn-toggle component. The group of buttons can be selected or toggled under a single v-model, which is bound to the format variable:

<template>
  <v-app>
    <v-row class="ma-2" justify="center">
      <v-btn-toggle v-model="format" borderless>
        <v-btn value="left">
          <span>Left</span><v-icon right>mdi-format-align-left</v-icon>
        </v-btn>
        <v-btn value="center">
          <span>Center</span><v-icon right>mdi-format-align-center</v-icon>
        </v-btn>
        <v-btn value="right">
          <span>Right</span><v-icon right>mdi-format-align-right</v-icon>
        </v-btn>
      </v-btn-toggle>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    format: 'center',
  }),
};
</script>
Creating a Vuetify toggle button.

Clicking one of the buttons in the group unselects the currently selected one:

Clicking another button in the button group.

Ensuring a Toggle Button Value with the mandatory Prop

Vuetify provides the mandatory prop, used to make sure that a toggle button will always have a value:

<template>
  <v-app>
    <v-row class="ma-2" justify="center">
      <v-btn-toggle v-model="format" borderless mandatory>
        <v-btn value="left">
          <span>Left</span><v-icon right>mdi-format-align-left</v-icon>
        </v-btn>
        <v-btn value="center">
          <span>Center</span><v-icon right>mdi-format-align-center</v-icon>
        </v-btn>
        <v-btn value="right">
          <span>Right</span><v-icon right>mdi-format-align-right</v-icon>
        </v-btn>
      </v-btn-toggle>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    format: null,
  }),
};
</script>
Vuetify toggle button with the mandatory prop.

Vuetify Toggle Button Multiple Selection

The multiple prop allows us to select more than one button in the group:

<template>
  <v-app>
    <v-row class="ma-2" justify="center">
      <v-btn-toggle v-model="selectedLetters" multiple>
        <v-btn v-for="(ch, index) in word" :key="index">{{ch}}</v-btn>
      </v-btn-toggle>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    word: 'Beauty'.split(''),
    selectedLetters: []
  }),
};
</script>
Vuetify toggle button with multiple selection enabled.

Vuetify Rounded Toggle Buttons

We can make toggle buttons in Vuetify rounded with the rounded prop:

<template>
  <v-app>
    <v-row class="ma-2" justify="center">
      <v-btn-toggle v-model="letter" rounded>
        <v-btn v-for="(ch, index) in word" :key="index">{{ ch }}</v-btn>
      </v-btn-toggle>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    word: 'Coding'.split(''),
    letter: '',
  }),
};
</script>
Rounded Vuetify button group.

Vuetify Borderless Toggle Buttons

Setting the borderless prop to true on a v-btn-toggle will remove the borders from each button in the group.

<template>
  <v-app>
    <v-row class="ma-2" justify="center">
      <v-btn-toggle v-model="letter" rounded borderless>
        <v-btn v-for="(ch, index) in word" :key="index">{{ ch }}</v-btn>
      </v-btn-toggle>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    word: 'Coding'.split(''),
    letter: '',
  }),
};
</script>
Borderless Vuetify button group component.

Customizing Toggle Button Colors in Vuetify

We can change the color of the selected button(s) in a button group with the color prop:

<template>
  <v-app>
    <v-row class="ma-2" justify="center">
      <v-btn-toggle v-model="selectedLetters" rounded multiple color="blue">
        <v-btn v-for="(ch, index) in word" :key="index">{{ ch }}</v-btn>
      </v-btn-toggle>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    word: 'Beauty'.split(''),
    selectedLetters: [],
  }),
};
</script>
Customizing a toggle button in Vuetify.

Summary

Toggle buttons are useful when we have a group of logically related buttons whose selection states need to be controlled by a single variable. Vuetify provides the v-btn-toggle component for creating them and various props for customization.