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 Bottom Sheet Component

A bottom sheet is a customized v-dialog that is anchored to the bottom of the screen, like a v-bottom-navigation. They are primarily used on mobile and can contain supplementary information and actions. In this article, we’re going to learn how to easily create and customize bottom sheets with the Vuetify bottom sheet component.

The Vuetify Bottom Sheet Component (v-bottom-sheet)

Vuetify provides the v-bottom-sheet component for creating a bottom sheet. Like v-dialog, this component comes with an activator slot that we can use to set a button that will open the sheet when clicked.

<template>
  <v-app>
    <div class="ma-4 text-center">
      <v-bottom-sheet v-model="sheet">
        <template v-slot:activator="{ on, attrs }">
          <v-btn
            v-bind="attrs"
            v-on="on"
            color="primary"
          >
            Open Sheet
          </v-btn>
        </template>
        <v-sheet
          class="text-center"
          height="200px"
        >
          <v-btn
            class="mt-6"
            text
            color="red"
            @click="sheet = !sheet"
          >
            close
          </v-btn>
          <div class="my-3">This is a bottom sheet</div>
        </v-sheet>
      </v-bottom-sheet>
    </div>
  </v-app>
</template>

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

<style>
html {
  overflow-y: auto !important;
}
</style>
Creating a bottom sheet with Vuetify.

Hide Overlay

v-bottom-sheet comes with a hide-overlay prop that will remove the overlay when set to true.

<template>
  <v-app>
    <div class="ma-4 text-center">
      <v-bottom-sheet
        v-model="sheet"
        hide-overlay
      >
        <template v-slot:activator="{ on, attrs }">
          <v-btn
            v-bind="attrs"
            v-on="on"
            color="primary"
          >
            Open Sheet
          </v-btn>
        </template>
        <v-sheet
          class="text-center"
          height="200px"
        >
          <v-btn
            class="mt-6"
            text
            color="red"
            @click="sheet = !sheet"
          >
            close
          </v-btn>
          <div class="my-3">This is a bottom sheet.</div>
        </v-sheet>
      </v-bottom-sheet>
    </div>
  </v-app>
</template>

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

<style>
html {
  overflow-y: auto !important;
}
</style>
Using the hide-overlay prop of the Vuetify bottom sheet component.

Vuetify Bottom Sheet v-model

We can set up a two-way binding between the value of the v-bottom-sheet and a variable. We can then use this variable to open/close the sheet or to display certain content conditionally.

<template>
  <v-app>
    <div class="ma-4 text-center">
      <div class="mb-4">
        The bottom sheet is {{ sheet ? 'open' : 'closed' }}
      </div>
      <v-bottom-sheet
        v-model="sheet"
        hide-overlay
      >
        <template v-slot:activator="{ on, attrs }">
          <v-btn
            v-bind="attrs"
            v-on="on"
            color="primary"
          >
            Open Sheet
          </v-btn>
        </template>
        <v-sheet
          class="text-center"
          height="200px"
        >
          <v-btn
            class="mt-6"
            text
            color="red"
            @click="sheet = !sheet"
          >
            close
          </v-btn>
          <div class="my-3">This is a bottom sheet</div>
        </v-sheet>
      </v-bottom-sheet>
    </div>
  </v-app>
</template>

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

<style>
html {
  overflow-y: auto !important;
}
</style>
Using v-model on a bottom sheet component.

Persistent Bottom Sheets

By default, an open bottom sheet closes when another element is clicked:

The bottom sheet closes when another element is clicked.

We can prevent this by setting the persistent prop to true on the v-bottom-sheet:

<template>
  <v-app>
    <div class="ma-4 text-center">
      <v-bottom-sheet
        v-model="sheet"
        persistent
      >
        <template v-slot:activator="{ on, attrs }">
          <v-btn
            v-bind="attrs"
            v-on="on"
            color="primary"
          >
            Open Sheet
          </v-btn>
        </template>
        <v-sheet
          class="text-center"
          height="200px"
        >
          <v-btn
            class="mt-6"
            text
            color="red"
            @click="sheet = !sheet"
          >
            close
          </v-btn>
          <div class="my-3">This is a bottom sheet.</div>
        </v-sheet>
      </v-bottom-sheet>
    </div>
  </v-app>
</template>

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

<style>
html {
  overflow-y: auto !important;
}
</style>
Using the persistent prop of the Vuetify bottom sheet component.

Vuetify Bottom Sheet Inset

The inset prop reduces the maximum width of the v-bottom-sheet to 70% on larger screens. We can also use the width prop to reduce the width manually.

<template>
  <v-app>
    <div class="ma-4 text-center">
      <v-bottom-sheet
        v-model="sheet"
        inset
      >
        <template v-slot:activator="{ on, attrs }">
          <v-btn
            v-bind="attrs"
            v-on="on"
            color="primary"
          >
            Open Sheet
          </v-btn>
        </template>
        <v-sheet
          class="text-center"
          height="200px"
        >
          <v-btn
            class="mt-6"
            text
            color="red"
            @click="sheet = !sheet"
          >
            close
          </v-btn>
          <div class="my-3">This is a bottom sheet.</div>
        </v-sheet>
      </v-bottom-sheet>
    </div>
  </v-app>
</template>

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

<style>
html {
  overflow-y: auto !important;
}
</style>
Using the inset prop of the Vuetify bottom sheet component.

Creating an “Open In” Component

We can combine a functional list and bottom sheet to create an “open in” component.

<template>
  <v-app>
    <div class="ma-4 text-center">
      <v-bottom-sheet v-model="sheet">
        <template v-slot:activator="{ on, attrs }">
          <v-btn
            v-bind="attrs"
            v-on="on"
            color="green"
            dark
          >
            Open in
          </v-btn>
        </template>
        <v-list>
          <v-subheader>Open in</v-subheader>
          <v-list-item
            v-for="(app, i) in apps"
            :key="i"
            @click="sheet = false"
          >
            <v-list-item-title>{{ app }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-bottom-sheet>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    sheet: false,
    apps: ['Firefox', 'Chrome', 'Edge', 'Opera'],
  }),
};
</script>

<style>
html {
  overflow-y: auto !important;
}
</style>
Creating an "open in" component with a bottom sheet and a list.

Conclusion

Bottom sheets are anchored to the bottom of the screen and can be used to display supplementary content. Vuetify provides the Vuetify bottom sheet component (v-bottom-sheet) for creating and customizing them.

How to Use the Vuetify Stepper Component

A stepper displays progress through a sequence by separating it into multiple logical and numbered steps. We can use it in scenarios like shopping carts, or cases where an input field determines a subsequent field. In this article, we’re going to learn how to use the Vuetify stepper component to easily create and customize steppers.

The Vuetify Stepper Component (v-stepper)

Vuetify provides the v-stepper component for creating a stepper. We indicate the steps with v-stepper-step components and display content for each step with v-stepper-content components. Every v-stepper-step or v-stepper-content has a step prop that we use to set the step it should be associated with. v-stepper-steps are typically wrapped in a v-stepper-header, while v-stepper-contents are wrapped in a v-stepper-items.

<template>
  <v-app>
    <div class="ma-4">
      <v-stepper v-model="step">
        <v-stepper-header>
          <v-stepper-step
            :complete="step > 1"
            step="1"
          >
            Step 1
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step
            :complete="step > 2"
            step="2"
          >
            Step 2
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step step="3"> Step 3 </v-stepper-step>
        </v-stepper-header>

        <v-stepper-items>
          <v-stepper-content step="1">
            <v-card
              class="mb-12"
              color="grey lighten-1"
              height="200px"
            ></v-card>

            <v-btn
              color="primary"
              @click="step = 2"
            >
              Continue
            </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>

          <v-stepper-content step="2">
            <v-card
              class="mb-12"
              color="grey lighten-1"
              height="200px"
            ></v-card>

            <v-btn
              color="primary"
              @click="step = 3"
            >
              Continue
            </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>

          <v-stepper-content step="3">
            <v-card
              class="mb-12"
              color="grey lighten-1"
              height="200px"
            ></v-card>

            <v-btn color="primary"> Continue </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>
        </v-stepper-items>
      </v-stepper>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    step: 1,
  }),
};
</script>
Creating a stepper with the Vuetify stepper component.

Clicking the “Continue” button moves the stepper to the next step with an animation:

Clicking the continue button moves the stepper to the next step.

Smaller Screens

The name of the steps are not shown on smaller screens:

The step names of the stepper are not shown on smaller screens.

Vuetify Stepper Alt Labels

Using the alt-labels prop on the v-stepper places the name of each step under the circle representing the step.

<template>
  <v-app>
    <div class="ma-4">
      <v-stepper
        v-model="step"
        alt-labels
      >
        <v-stepper-header>
          <v-stepper-step
            :complete="step > 1"
            step="1"
          >
            Step 1
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step
            :complete="step > 2"
            step="2"
          >
            Step 2
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step step="3"> Step 3 </v-stepper-step>
        </v-stepper-header>
      </v-stepper>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    step: 1,
  }),
};
</script>
Using the alt-labels prop of the Vuetify stepper component.

Stepper Color

With the color prop of the v-stepper-steps, we can customize the color of completed steps or the current step. We can use any color from the Material Design specs.

<template>
  <v-app>
    <div class="ma-4">
      <v-stepper
        value="3"
      >
        <v-stepper-header>
          <v-stepper-step
            complete
            step="1"
            color="green"
          >
            Step 1
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step
            complete
            step="2"
            color="green"
          >
            Step 2
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step
            step="3"
            color="green"
          >
            Step 3
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step
            step="4"
            color="green"
          >
            Step 4
          </v-stepper-step>
        </v-stepper-header>
      </v-stepper>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Customizing the color of steps on the stepper.

Editable Steps

An editable step allows the user to return later to modify it. We can make a step editable by setting the editable prop to true on the v-stepper-step associated with it.

<template>
  <v-app>
    <div class="ma-4">
      <v-stepper
        v-model="step"
        alt-labels
        non-linear
      >
        <v-stepper-header>
          <v-stepper-step
            complete
            editable
            step="1"
          >
            Step 1
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step
            editable
            step="2"
          >
            Step 2
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step
            step="3"
            complete
            editable
          >
            Step 3
          </v-stepper-step>
        </v-stepper-header>

        <v-stepper-items>
          <v-stepper-content step="1">
            <v-card
              class="mb-12 pa-4"
              color="text-h2 text-center"
              height="200px"
            >
              <div>Step 1</div>
            </v-card>

            <v-btn
              color="primary"
              @click="step = 2"
            >
              Continue
            </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>

          <v-stepper-content step="2">
            <v-card
              class="mb-12 pa-4"
              color="text-h2 text-center"
              height="200px"
            >
              <div>Step 2</div>
            </v-card>

            <v-btn
              color="primary"
              @click="step = 3"
            >
              Continue
            </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>

          <v-stepper-content step="3">
            <v-card
              class="mb-12 pa-4"
              color="text-h2 text-center"
              height="200px"
            >
              <div>Step 3</div>
            </v-card>

            <v-btn color="primary"> Continue </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>
        </v-stepper-items>
      </v-stepper>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    step: 1,
  }),
};
</script>
Creating a stepper with editable steps.

Non-editable Steps

Non-editable steps prevent modification once completed. A step is non-editable if the associated v-stepper-step does not have its step prop set to true.

<template>
  <v-app>
    <div class="ma-4">
      <v-stepper
        v-model="step"
        alt-labels
        non-linear
      >
        <v-stepper-header>
          <v-stepper-step
            complete
            editable
            step="1"
          >
            Step 1
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step
            editable
            step="2"
          >
            Step 2
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step
            step="3"
            complete
          >
            Step 3
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step
            step="4"
            complete
            editable
          >
            Step 4
          </v-stepper-step>
        </v-stepper-header>

        <v-stepper-items>
          <v-stepper-content step="1">
            <v-card
              class="mb-12 pa-4"
              color="text-h2 text-center"
              height="200px"
            >
              <div>Step 1</div>
            </v-card>

            <v-btn
              color="primary"
              @click="step = 2"
            >
              Continue
            </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>

          <v-stepper-content step="2">
            <v-card
              class="mb-12 pa-4"
              color="text-h2 text-center"
              height="200px"
            >
              <div>Step 2</div>
            </v-card>

            <v-btn
              color="primary"
              @click="step = 3"
            >
              Continue
            </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>

          <v-stepper-content step="3">
            <v-card
              class="mb-12 pa-4"
              color="text-h2 text-center"
              height="200px"
            >
              <div>Step 3</div>
            </v-card>

            <v-btn color="primary"> Continue </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>

          <v-stepper-content step="4">
            <v-card
              class="mb-12 pa-4"
              color="text-h2 text-center"
              height="200px"
            >
              <div>Step 4</div>
            </v-card>

            <v-btn color="primary"> Continue </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>
        </v-stepper-items>
      </v-stepper>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    step: 1,
  }),
};
</script>
Creating a stepper with non-editable steps.

Vuetify Stepper Linear

Linear steppers move users through the defined path. One step must be completed before moving on to the next.

<template>
  <v-app>
    <div class="ma-4">
      <v-stepper alt-labels>
        <v-stepper-header>
          <v-stepper-step step="1"> Step 1 </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step step="2"> Step 2 </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step step="3"> Step 3 </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step step="4"> Step 4 </v-stepper-step>
        </v-stepper-header>
      </v-stepper>

      <v-stepper
        alt-labels
        value="2"
        class="mt-12"
      >
        <v-stepper-header>
          <v-stepper-step
            step="1"
            complete
          >
            Step 1
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step step="2"> Step 2 </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step step="3"> Step 3 </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step step="4"> Step 4 </v-stepper-step>
        </v-stepper-header>
      </v-stepper>

      <v-stepper
        alt-labels
        value="3"
        class="mt-12"
      >
        <v-stepper-header>
          <v-stepper-step
            step="1"
            complete
          >
            Step 1
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            step="2"
            complete
          >
            Step 2
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step step="3"> Step 3 </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step step="4"> Step 4 </v-stepper-step>
        </v-stepper-header>
      </v-stepper>

      <v-stepper
        alt-labels
        value="4"
        class="mt-12"
      >
        <v-stepper-header>
          <v-stepper-step
            step="1"
            complete
          >
            Step 1
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            step="2"
            complete
          >
            Step 2
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            step="3"
            complete
          >
            Step 3
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step step="4"> Step 4 </v-stepper-step>
        </v-stepper-header>
      </v-stepper>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Creating a linear stepper with Vuetify.

Vuetify Stepper Non-linear

A non-linear stepper allow the user to move through your process in their preferred way.

<template>
  <v-app>
    <div class="ma-4">
      <v-stepper non-linear>
        <v-stepper-header>
          <v-stepper-step
            step="1"
            editable
          >
            Step 1
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            step="2"
            editable
          >
            Step 2
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            step="3"
            editable
          >
            Step 3
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            step="4"
            editable
          >
            Step 4
          </v-stepper-step>
        </v-stepper-header>
      </v-stepper>

      <v-stepper
        value="4"
        class="mt-12"
        non-linear
      >
        <v-stepper-header>
          <v-stepper-step
            step="1"
            complete
            editable
          >
            Step 1
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            step="2"
            editable
          >
            Step 2
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            step="3"
            editable
          >
            Step 3
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            step="4"
            editable
          >
            Step 4
          </v-stepper-step>
        </v-stepper-header>
      </v-stepper>

      <v-stepper
        value="2"
        class="mt-12"
        non-linear
      >
        <v-stepper-header>
          <v-stepper-step
            step="1"
            complete
            editable
          >
            Step 1
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            step="2"
            editable
          >
            Step 2
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            step="3"
            editable
          >
            Step 3
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            step="4"
            editable
            complete
          >
            Step 4
          </v-stepper-step>
        </v-stepper-header>
      </v-stepper>

      <v-stepper
        value="3"
        class="mt-12"
        non-linear
      >
        <v-stepper-header>
          <v-stepper-step
            step="1"
            complete
            editable
          >
            Step 1
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            step="2"
            complete
            editable
          >
            Step 2
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            step="3"
            editable
          >
            Step 3
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            step="4"
            editable
            complete
          >
            Step 4
          </v-stepper-step>
        </v-stepper-header>
      </v-stepper>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Creating a non-linear stepper with Vuetify.

Vuetify Stepper Vertical

A vertical stepper moves users through the steps along the y-axis and works similarly to a horizontal stepper. We can make a stepper vertical by setting the vertical prop of the v-stepper to true.

<template>
  <v-app>
    <div class="ma-4">
      <v-stepper
        v-model="step"
        vertical
      >
        <v-stepper-items>
          <v-stepper-step
            :complete="step > 1"
            step="1"
          >
            Step 1
          </v-stepper-step>
          <v-stepper-content step="1">
            <v-card
              class="mb-12"
              color="grey lighten-1"
              height="200px"
            ></v-card>

            <v-btn
              color="primary"
              @click="step = 2"
            >
              Continue
            </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>

          <v-stepper-step
            :complete="step > 2"
            step="2"
          >
            Step 2
          </v-stepper-step>
          <v-stepper-content step="2">
            <v-card
              class="mb-12"
              color="grey lighten-1"
              height="200px"
            ></v-card>

            <v-btn
              color="primary"
              @click="step = 3"
            >
              Continue
            </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>

          <v-stepper-content step="3">
            <v-stepper-step step="3">
              Step 3
            </v-stepper-step>

            <v-card
              class="mb-12"
              color="grey lighten-1"
              height="200px"
            ></v-card>

            <v-btn color="primary"> Continue </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>
        </v-stepper-items>
      </v-stepper>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    step: 1,
  }),
};
</script>
Creating a vertical stepper with Vuetify.

Vuetify Stepper Horizontal

Horizontal steppers move the user through the steps along the x-axis. v-steppers are horizontal by default.

<template>
  <v-app>
    <div class="ma-4">
      <v-stepper value="3">
        <v-stepper-header>
          <v-stepper-step
            complete
            step="1"
          >
            Step 1
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step
            complete
            step="2"
          >
            Step 2
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step step="3"> Step 3 </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step step="4"> Step 4 </v-stepper-step>
        </v-stepper-header>
      </v-stepper>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Creating a horizontal stepper with Vuetify.

Vuetify Stepper Error Messages

We can display an error state on the stepper to indicate a compulsory action.

<template>
  <v-app>
    <div class="ma-4">
      <v-stepper
        v-model="step"
        alt-labels
        non-linear
      >
        <v-stepper-header>
          <v-stepper-step
            complete
            step="1"
          >
            Step 1
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step
            editable
            step="2"
          >
            Step 2
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step
            step="3"
            editable
            :rules="step3Rules"
          >
            <div class="text-center">
              Step 3
              <small>Alert message</small>
            </div>
          </v-stepper-step>

          <v-divider></v-divider>

          <v-stepper-step
            step="4"
            editable
          >
            Step 4
          </v-stepper-step>
        </v-stepper-header>
        <v-stepper-items>
          <v-stepper-content step="1">
            <v-card
              class="mb-12 pa-4"
              color="text-h2 text-center"
              height="200px"
            >
              <div>Step 1</div>
            </v-card>

            <v-btn
              color="primary"
              @click="step = 2"
            >
              Continue
            </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>

          <v-stepper-content step="2">
            <v-card
              class="mb-12 pa-4"
              color="text-h2 text-center"
              height="200px"
            >
              <div>Step 2</div>
            </v-card>

            <v-btn
              color="primary"
              @click="step = 3"
            >
              Continue
            </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>

          <v-stepper-content step="3">
            <v-card
              class="mb-12 pa-4"
              color="text-h2 text-center"
              height="200px"
            >
              <div>Step 3</div>
            </v-card>

            <v-btn color="primary"> Continue </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>

          <v-stepper-content step="4">
            <v-card
              class="mb-12 pa-4"
              color="text-h2 text-center"
              height="200px"
            >
              <div>Step 4</div>
            </v-card>

            <v-btn color="primary"> Continue </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>
        </v-stepper-items>
      </v-stepper>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    step: 1,
    step3Rules: [(value) => false],
  }),
};
</script>
Displaying an error state in a horizontal stepper.

We can also display an error state in a vertical stepper:

<template>
  <v-app>
    <div class="ma-4">
      <v-stepper
        v-model="step"
        vertical
      >
        <v-stepper-items>
          <v-stepper-step
            :complete="step > 1"
            step="1"
          >
            Step 1
          </v-stepper-step>
          <v-stepper-content step="1">
            <v-card
              class="mb-12"
              color="grey lighten-1"
              height="200px"
            ></v-card>

            <v-btn
              color="primary"
              @click="step = 2"
            >
              Continue
            </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>

          <v-stepper-step
            step="2"
            :rules="step2Rules"
            editable
          >
            Step 2
            <small>Alert message</small>
          </v-stepper-step>
          <v-stepper-content step="2">
            <v-card
              class="mb-12"
              color="grey lighten-1"
              height="200px"
            ></v-card>

            <v-btn
              color="primary"
              @click="step = 3"
            >
              Continue
            </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>

          <v-stepper-content step="3">
            <v-stepper-step
              step="3"
              editable
            >
              Step 3
            </v-stepper-step>

            <v-card
              class="mb-12"
              color="grey lighten-1"
              height="200px"
            ></v-card>

            <v-btn color="primary"> Continue </v-btn>

            <v-btn text> Cancel </v-btn>
          </v-stepper-content>
        </v-stepper-items>
      </v-stepper>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    step: 1,
    step2Rules: [() => false],
  }),
};
</script>
Displaying an error state in a vertical stepper.

Optional Steps

We can indicate optional steps in the stepper with sub-text.

<template>
  <v-app>
    <div class="ma-4">
      <v-stepper value="3">
        <v-stepper-header>
          <v-stepper-step
            step="1"
            complete
          >
            Step 1
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            step="2"
            complete
          >
            Step 2
          </v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step step="3">
            Step 3 <small>Optional</small></v-stepper-step
          >
          <v-divider></v-divider>
          <v-stepper-step step="4"> Step 4 </v-stepper-step>
        </v-stepper-header>
      </v-stepper>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Indicate optional steps in the stepper.

Conclusion

A stepper displays progress through numbered steps. We can use the Vuetify stepper component (v-stepper) and its various sub-components to create and customize steppers.

How to Use the Vuetify Sparkline Component

We can use a sparkline to give a visual representation of numerical or statistical information with simple graphs. In this extensive guide, we’ll learn how to use the Vuetify sparkline component to easily create and customize sparklines.

The Vuetify Sparkline Component (v-sparkline)

Vuetify provides the v-sparkline component for creating a sparkline. It has a value prop that takes an array containing the data to be represented:

<template>
  <v-app>
    <div class="ma-4">
      <v-sparkline
        :value="value"
        smooth="10"
      ></v-sparkline>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: [0, 4, 2, 7, 6, 9, 4, 8, 0, 0, 2, 7, 3, 10, 5],
  }),
};
</script>
Creating a sparkline with the Vuetify sparkline component.

Vuetify Sparkline Stroke Line Cap

The sparkline has a sharp line cap by default. We can make it round by setting the stroke-linecap prop to round:

<template>
  <v-app>
    <div class="ma-4">
      <v-sparkline
        :value="value"
        smooth="10"
        stroke-linecap="round"
      ></v-sparkline>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: [0, 4, 2, 7, 6, 9, 4, 8, 0, 0, 2, 7, 3, 10, 5],
  }),
};
</script>
Using the stroke-linecap prop of the Vuetify sparkline component.

Vuetify Sparkline Fill

We can color the region below the sparkline by setting the fill prop to true:

<template>
  <v-app>
    <div class="ma-4">
      <v-sparkline
        :value="value"
        smooth="10"
        fill
      ></v-sparkline>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: [0, 4, 2, 7, 6, 9, 4, 8, 0, 0, 2, 7, 3, 10, 5],
  }),
};
</script>
Using the fill prop of the Vuetify sparkline component.

Vuetify Sparkline Line Width

We can use the line-width prop to control the thickness of the sparkline.

<template>
  <v-app>
    <div class="ma-4">
      <v-sparkline
        :value="value"
        smooth="10"
        line-width="2"
        stroke-linecap="round"
      ></v-sparkline>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: [0, 4, 2, 7, 6, 9, 4, 8, 0, 0, 2, 7, 3, 10, 5],
  }),
};
</script>
Using the line-width prop of the Vuetify sparkline component.

Sparkline Color

v-sparkline comes with a color prop for customizing the color of the sparkline. We can use any color from the Material design specs.

<template>
  <v-app>
    <div class="ma-4">
      <v-sparkline
        :value="value"
        smooth="10"
        color="red accent-2"
        stroke-linecap="round"
      ></v-sparkline>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: [0, 4, 2, 7, 6, 9, 4, 8, 0, 0, 2, 7, 3, 10, 5],
  }),
};
</script>
Customizing the color of the Vuetify sparkline component.

Vuetify Sparkline Smooth

With the smooth prop, we can set the roundness of the corners formed from the sparkline tracing the data points. We can pass a number or a boolean value to smooth. Setting it to true sets a corner radius of 8px. In the code example below, we set it to 5 (for a corner radius of 5px):

<template>
  <v-app>
    <div class="ma-4">
      <v-sparkline
        :value="value"
        smooth="5"
        stroke-linecap="round"
      ></v-sparkline>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: [0, 4, 2, 7, 6, 9, 4, 8, 0, 0, 2, 7, 3, 10, 5],
  }),
};
</script>
Using the smooth prop of the Vuetify sparkline component.

Setting smooth to false will set the corner radius to 0px:

<template>
  <v-app>
    <div class="ma-4">
      <v-sparkline
        :value="value"
        :smooth="false"
      ></v-sparkline>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: [0, 4, 2, 7, 6, 9, 4, 8, 0, 0, 2, 7, 3, 10, 5],
  }),
};
</script>
Setting the smooth prop to false on the Vuetify sparkline component.

Vuetify Sparkline Padding

We can add padding to the sparkline with the padding property. It has a padding of 8 by default.

<template>
  <v-app>
    <v-card class="ma-4">
      <v-sparkline
        :value="value"
        smooth="10"
        padding="10"
        stroke-linecap="round"
      ></v-sparkline>
    </v-card>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: [0, 4, 2, 7, 6, 9, 4, 8, 0, 0, 2, 7, 3, 10, 5],
  }),
};
</script>
Using the padding prop of the Vuetify sparkline component.

Vuetify Sparkline Auto Draw

Setting the auto-draw prop to true on a v-sparkline will make the sparkline run a trace animation when first rendered.

<template>
  <v-app>
    <div class="ma-4">
      <v-sparkline
        :value="value"
        smooth="10"
        padding="10"
        stroke-linecap="round"
        auto-draw
      ></v-sparkline>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: [0, 4, 2, 7, 6, 9, 4, 8, 0, 0, 2, 7, 3, 10, 5],
  }),
};
</script>
Using the auto-draw prop of the Vuetify sparkline component.

Sparkline Auto Draw Duration

The auto-draw-duration prop allows us to set the duration of the trace animation in milliseconds. It has a default value of 2000 (2 seconds).

<template>
  <v-app>
    <div class="ma-4">
      <v-sparkline
        :value="value"
        smooth="10"
        padding="10"
        stroke-linecap="round"
        auto-draw
        :auto-draw-duration="4000"
      ></v-sparkline>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: [0, 4, 2, 7, 6, 9, 4, 8, 0, 0, 2, 7, 3, 10, 5],
  }),
};
</script>
Using the auto-draw-duration prop of the Vuetify sparkline component.

Sparkline Auto Draw Easing

We can specify the easing function of the trace animation with the auto-draw-easing prop:

<template>
  <v-app>
    <div class="ma-4">
      <v-sparkline
        :value="value"
        smooth="10"
        padding="10"
        stroke-linecap="round"
        auto-draw
        :auto-draw-duration="4000"
        auto-draw-easing="linear"
      ></v-sparkline>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: [0, 4, 2, 7, 6, 9, 4, 8, 0, 0, 2, 7, 3, 10, 5],
  }),
};
</script>
Using the auto-draw-easing prop of the Vuetify sparkline component.

Vuetify Sparkline Type

By setting the type prop to bar, we can make v-sparkline show a set of bars instead of a line. The default type is trend which shows the continuous line.

<template>
  <v-app>
    <div class="ma-4">
      <v-sparkline
        :value="value"
        smooth="10"
        padding="10"
        stroke-linecap="round"
        type="bar"
      ></v-sparkline>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: [0, 4, 2, 7, 6, 9, 4, 8, 0, 0, 2, 7, 3, 10, 5],
  }),
};
</script>
Using the type prop of the Vuetify sparkline component.

Vuetify Sparkline Gradient

We can set the color of the sparkline to a linear gradient with the gradient prop. gradient takes an array of colors to use for the linear gradient.

<template>
  <v-app>
    <div class="ma-4">
      <v-sparkline
        :value="value"
        smooth="10"
        padding="10"
        stroke-linecap="round"
        :gradient="gradient"
      ></v-sparkline>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: [0, 4, 2, 7, 6, 9, 4, 8, 0, 0, 2, 7, 3, 10, 5],
    gradient: ['red', 'orange', 'yellow'],
  }),
};
</script>
Using the gradient prop of the Vuetify sparkline component.

Vuetify Sparkline Gradient Direction

The gradient-direction property of v-sparkline sets the direction in which the color gradient should run.

<template>
  <v-app>
    <div class="ma-4">
      <v-sparkline
        :value="value"
        smooth="10"
        padding="10"
        stroke-linecap="round"
        :gradient="gradient"
        gradient-direction="bottom"
      ></v-sparkline>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: [0, 4, 2, 7, 6, 9, 4, 8, 0, 0, 2, 7, 3, 10, 5],
    gradient: ['red', 'orange', 'yellow'],
  }),
};
</script>

Conclusion

A sparkline displays simple graphs that visually represent numerical or statistical information. We can use the Vuetify sparkline component (v-sparkline) and its various prop to create and customize sparklines.

How to Use Vuetify Overflow Helper Classes

Vuetify provides utility classes that allow us to easily configure how content overflows when its size becomes greater than the bounds of its container. We’re going to learn how to use them in this article.

The classes are in the format {overflow}-{value}. overflow can be any of overflow, overflow-x and overflow-y, while value can be any of auto, hidden and visible. Here are all the overflow helper classes from Vuetify:

  • overflow-auto
  • overflow-hidden
  • overflow-visible
  • overflow-x-auto
  • overflow-x-hidden
  • overflow-x-visible
  • overflow-y-auto
  • overflow-y-hidden
  • overflow-y-visible

Vuetify Overflow Classes

  • overflow-auto: adds scrollbars to an element when its content overflows it bounds in the vertical or horizontal direction.
  • overflow-hidden: clips content that overflows the bounds of its container in the vertical or horizontal direction.
  • overflow-visible: allows content to be rendered outside the bounds of its container in the vertical or horizontal direction.
<template>
  <v-app>
    <v-row class="ma-4">
      <v-col cols="4">
        <v-card
          class="overflow-auto"
          height="200"
        >
          <v-card-text style="width: 300px">
            <h3>Overflow Auto</h3>
            Lorem ipsum dolor sit amet consectetur
            adipisicing elit. Quam repudiandae magnam dolor
            asperiores nisi officia, necessitatibus, ex
            alias consequuntur ullam qui optio, obcaecati
            minima modi quaerat explicabo. Quia, ipsa minus.
            Lorem ipsum dolor, sit amet consectetur
            adipisicing elit. Delectus, voluptatum? Nobis
            ratione eos praesentium. Iusto pariatur magni
            eveniet provident hic incidunt iure minima
            voluptatem. Corrupti alias delectus in culpa
            quis.
          </v-card-text>
        </v-card>
      </v-col>
      <v-col cols="4">
        <v-card
          class="overflow-hidden"
          height="200"
        >
          <v-card-text style="width: 300px">
            <h3>Overflow Hidden</h3>
            Lorem ipsum dolor sit amet consectetur
            adipisicing elit. Quam repudiandae magnam dolor
            asperiores nisi officia, necessitatibus, ex
            alias consequuntur ullam qui optio, obcaecati
            minima modi quaerat explicabo. Quia, ipsa minus.
            Lorem ipsum dolor, sit amet consectetur
            adipisicing elit. Delectus, voluptatum? Nobis
            ratione eos praesentium. Iusto pariatur magni
            eveniet provident hic incidunt iure minima
            voluptatem. Corrupti alias delectus in culpa
            quis.
          </v-card-text>
        </v-card>
      </v-col>
      <v-col cols="4">
        <v-card
          class="overflow-visible"
          height="200"
        >
          <v-card-text style="width: 300px">
            <h3>Overflow Visible</h3>
            Lorem ipsum dolor sit amet consectetur
            adipisicing elit. Quam repudiandae magnam dolor
            asperiores nisi officia, necessitatibus, ex
            alias consequuntur ullam qui optio, obcaecati
            minima modi quaerat explicabo. Quia, ipsa minus.
            Lorem ipsum dolor, sit amet consectetur
            adipisicing elit. Delectus, voluptatum? Nobis
            ratione eos praesentium. Iusto pariatur magni
            eveniet provident hic incidunt iure minima
            voluptatem. Corrupti alias delectus in culpa
            quis.
          </v-card-text>
        </v-card>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the Vuetify overflow helpers for the vertical and horizontal directions.

Vuetify Overflow Y Classes

  • overflow-y-auto: adds scrollbars to an element when its content overflows it bounds in the vertical direction.
  • overflow-y-hidden: clips content that overflows the bounds of its container in the vertical direction.
  • overflow-y-visible: allows content to be rendered outside the bounds of its container in the vertical direction.
<template>
  <v-app>
    <v-row class="ma-4">
      <v-col cols="4">
        <v-card
          class="overflow-y-auto"
          height="200"
        >
          <v-card-text>
            <h3>Overflow Y Auto</h3>
            Lorem ipsum dolor sit amet consectetur
            adipisicing elit. Praesentium, culpa eum
            repellat asperiores ad alias voluptas. Aliquid
            consectetur, quo delectus distinctio
            voluptatibus, numquam sequi hic eum mollitia
            optio quam esse?
          </v-card-text>
        </v-card>
      </v-col>
      <v-col cols="4">
        <v-card
          class="overflow-y-hidden"
          height="200"
        >
          <v-card-text>
            <h3>Overflow Y Hidden</h3>
            Lorem ipsum dolor sit amet consectetur
            adipisicing elit. Praesentium, culpa eum
            repellat asperiores ad alias voluptas. Aliquid
            consectetur, quo delectus distinctio
            voluptatibus, numquam sequi hic eum mollitia
            optio quam esse?
          </v-card-text>
        </v-card>
      </v-col>
      <v-col cols="4">
        <v-card
          class="overflow-y-visible"
          height="200"
        >
          <v-card-text>
            <h3>Overflow Y Visible</h3>
            Lorem ipsum dolor sit amet consectetur
            adipisicing elit. Praesentium, culpa eum
            repellat asperiores ad alias voluptas. Aliquid
            consectetur, quo delectus distinctio
            voluptatibus, numquam sequi hic eum mollitia
            optio quam esse?
          </v-card-text>
        </v-card>
      </v-col>
    </v-row>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the Vuetify overflow Y helpers for the vertical direction.

Vuetify Overflow X Classes

  • overflow-x-auto: adds scrollbars to an element when its content overflows it bounds in the horizontal direction.
  • overflow-x-hidden: clips content that overflows the bounds of its container in the horizontal direction.
  • overflow-x-visible: allows content to be rendered outside the bounds of its container in the horizontal direction.
<template>
  <v-app>
    <div style="width: 300px;white-space:nowrap" class="ma-4">
      <h3 class="mb-3">Overflow X Auto</h3>
      <p class="overflow-x-auto blue lighten-4">
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Quam repudiandae magnam dolor asperiores nisi officia, necessitatibus, ex alias consequuntur ullam qui optio, obcaecati minima modi quaerat explicabo. Quia, ipsa minus.
      </p>
      <h3 class="mb-3">Overflow X Hidden</h3>
      <p class="overflow-x-hidden blue lighten-4">
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Quam repudiandae magnam dolor asperiores nisi officia, necessitatibus, ex alias consequuntur ullam qui optio, obcaecati minima modi quaerat explicabo. Quia, ipsa minus.
      </p>
      <h3 class="mb-3">Overflow X Visible</h3>
      <p class="overflow-x-visible blue lighten-4">
        Lorem ipsum dolor sit amet consectetur adipisicing elit. Quam repudiandae magnam dolor asperiores nisi officia, necessitatibus, ex alias consequuntur ullam qui optio, obcaecati minima modi quaerat explicabo. Quia, ipsa minus.
      </p>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the Vuetify overflow X helpers for the horizontal direction.

Conclusion

We can use the overflow helper classes from Vuetify to control what happens to content that overflows the bounds of its container in the vertical or horizontal direction.

How to Create a Calendar With Vuetify

In this article, we’ll learn about the Vuetify calendar component and its various props and slots for creating and customizing calendars that can display events and other time-related information in various ways.

The Vuetify calendar component (v-calendar)

Vuetify provides the v-calendar component for displaying a calendar.

App.vue
<template> <v-app> <div class="ma-4" style="height: 100%" > <v-calendar></v-calendar> </div> </v-app> </template> <script> export default { name: 'App', }; </script> 
Displaying a calendar with the Vuetify calendar component.

Vuetify calendar events

We can display events in the calendar with the events prop. This property takes an array with each element representing one event. Each item in the array is an object that has a number of properties, including:

  • name: sets the name of the event.
  • start: sets the start date of the event.
  • end: sets the end date of the event.
  • timed: specifies whether the event has a defined time range or not.
App.vue
<template> <v-app> <div class="ma-4" style="height: 100%" > <v-calendar :events="events" now="2022-04-17" ></v-calendar> </div> </v-app> </template> <script> export default { name: 'App', data: () => { return { events: [ { name: 'Event 1', start: '2022-04-01', timed: false, }, { name: 'Event 2', start: '2022-04-05', end: '2022-04-07', }, { name: 'Event 3', start: '2022-04-09T08:00:00', end: '2022-04-09T10:00:00', timed: true, }, ], }; }, }; </script> 
Using the events prop of the Vuetify calendar component.

Vuetify calendar colors

The v-calendar component provides various ways of customizing the colors of its different parts. For example, we can set the color of a single event by passing a value to the color property of the object representing the event:

App.vue
<template> <v-app> <div class="ma-4" style="height: 100%" > <v-calendar :events="events" now="2022-04-17" ></v-calendar> </div> </v-app> </template> <script> export default { name: 'App', data: () => { return { events: [ { name: 'Event 1', start: '2022-04-01', timed: false, color: 'green', }, { name: 'Event 2', start: '2022-04-05', end: '2022-04-07', color: 'yellow darken-3', }, { name: 'Event 3', start: '2022-04-09T08:00:00', end: '2022-04-09T10:00:00', timed: true, color: 'red', }, ], }; }, }; </script> 
Customizing event colors on the Vuetify calendar component.

event-color and color props

We can also the event-color prop to set the color of all events without a specified color. The color prop of v-calendar sets the color of the circle that indicates the current date in the calendar, and the color of the current day of the week.

App.vue
<template> <v-app> <div class="ma-4" style="height: 100%" > <v-calendar :events="events" now="2022-04-17" event-color="red accent-2" color="red accent-2" > </v-calendar> </div> </v-app> </template> <script> export default { name: 'App', data: () => { return { events: [ { name: 'Event 1', start: '2022-04-01', timed: false, }, { name: 'Event 2', start: '2022-04-05', end: '2022-04-07', }, { name: 'Event 3', start: '2022-04-09T08:00:00', end: '2022-04-09T10:00:00', timed: true, }, ], }; }, }; </script> 
Using the event-color and color props of the Vuetify calendar component.

Vuetify calendar day view

By default, the calendar component displays information for each month. We can customize the view the calendar shows with the type prop. We can display information just for a particular day by setting type to day:

JavaScript
<template> <v-app> <div class="ma-4" style="height: 100%" > <v-calendar :events="events" now="2022-04-17" value="2022-04-20" type="day" ></v-calendar> </div> </v-app> </template> <script> export default { name: 'App', data: () => { return { events: [ { name: 'Event 1', start: '2022-04-20T02:00:00', end: '2022-04-20T04:00:00', timed: true, }, { name: 'Event 2', start: '2022-04-20T05:00:00', end: '2022-04-20T06:00:00', timed: true, }, { name: 'Event 3', start: '2022-04-20T09:00:00', end: '2022-04-20T10:00:00', timed: true, }, ], }; }, }; </script> 
Displaying the day view of the Vuetify calendar component.

Calendar day view slots

day-header and interval

There are various slots of the v-calendar component that we use to customize how the calendar displays in the day view. We can use the day-header slot to customize the content that is placed in the top container in the day view. We also have the interval slot, for customizing the content that is placed in the interval space in the day view.

App.vue
<template> <v-app> <div class="ma-4" style="height: 100%" > <v-calendar :events="events" now="2022-04-17" value="2022-04-20" type="day" > <template v-slot:day-header="{ present }"> <div v-if="present" class="text-center" > Today </div> </template> <template v-slot:interval="{ hour }"> <div class="text-center">{{ hour }} o'clock</div> </template> </v-calendar> </div> </v-app> </template> <script> export default { name: 'App', data: () => { return { events: [ { name: 'Event 1', start: '2022-04-20T02:00:00', end: '2022-04-20T04:00:00', timed: true, }, { name: 'Event 2', start: '2022-04-20T05:00:00', end: '2022-04-20T06:00:00', timed: true, }, { name: 'Event 3', start: '2022-04-20T09:00:00', end: '2022-04-20T10:00:00', timed: true, }, ], }; }, }; </script> 
Using the day-header and the interval slots of the Vuetify calendar component.

day-body

The day-body slot allows us to customize the content in the scrollable interval container in the day view of the calendar.

App.vue
<template> <v-app> <div class="ma-4" style="height: 100%" > <v-calendar ref="calendar" type="week" value="2022-04-13" > <template v-slot:day-body="{ date, week }"> <div class="current-time" :class="{ first: date === week[0].date }" :style="{ top: nowY }" ></div> </template> </v-calendar> </div> </v-app> </template> <script> export default { name: 'App', data: () => ({ ready: false, }), computed: { cal() { return this.ready ? this.$refs.calendar : null; }, nowY() { return this.cal ? this.cal.timeToY({ hour: 8, minute: 10 }) + 'px' : '-10px'; }, }, mounted() { this.ready = true; this.scrollToTime(); this.updateTime(); }, methods: { getCurrentTime() { return this.cal ? this.cal.times.now.hour * 60 + this.cal.times.now.minute : 0; }, scrollToTime() { const time = this.getCurrentTime(); const first = Math.max(0, time - (time % 30) - 30); this.cal.scrollToTime(first); }, updateTime() { setInterval(() => this.cal.updateTimes(), 60 * 1000); }, }, }; </script> <style lang="scss"> .current-time { height: 2px; background-color: red; position: absolute; left: -1px; right: 0; pointer-events: none; &.first::before { content: ''; position: absolute; background-color: red; width: 12px; height: 12px; border-radius: 50%; margin-top: -5px; margin-left: -6.5px; } } </style> 
Using the day-body slot of the Vuetify calendar component.

Calendar week view

We can set the type prop to week to make the calendar display information only for a particular week:

App.vue
<template> <v-app> <div class="ma-4" style="height: 100%" > <v-calendar :events="events" type="week" event-color="indigo" value="2022-04-16" now="2022-04-16" > </v-calendar> </div> </v-app> </template> <script> export default { name: 'App', data: () => { return { events: [ { name: 'Event 1', start: '2022-04-10T02:00:00', end: '2022-04-10T04:00:00', timed: true, }, { name: 'Event 2', start: '2022-04-12T08:00:00', end: '2022-04-12T10:00:00', timed: true, }, { name: 'Event 3', start: '2022-04-15T04:00:00', end: '2022-04-15T06:00:00', timed: true, }, ], }; }, }; </script> 
Displaying the week view of the Vuetify calendar component.

Vuetify calendar click events

v-calendar comes with certain click events that we can use to add interactivity to the calendar. For example, we can listen for the @click:day event to perform an action when the user clicks a day in the calendar. Similarly, we can listen for the @click:event event to perform an action when the user clicks on an event in the calendar. We use both click events in the code example below.

App.vue
<template> <v-app> <div class="ma-4" style="height: 100%" > <!-- Event details menu --> <v-menu v-model="selectedOpen" :close-on-content-click="false" :activator="selectedElement" offset-x > <v-card min-width="200px"> <v-toolbar color="purple accent-4" dark > <v-toolbar-title> {{ selectedEvent.name }} </v-toolbar-title> </v-toolbar> <v-card-text> <div class="text-center"> {{ selectedEventStart }} to {{ selectedEventEnd }} </div> <v-checkbox readonly label="All day" :value="!selectedEvent.timed" > </v-checkbox> </v-card-text> </v-card> </v-menu> <v-calendar :events="events" event-color="purple accent-4" @click:day="viewDay" @click:event="showEvent" v-model="focus" :type="type" now="2022-04-23" ></v-calendar> </div> </v-app> </template> <script> import { format } from 'date-fns'; export default { name: 'App', data: () => { return { focus: '', type: 'month', selectedOpen: false, selectedElement: undefined, selectedEvent: {}, events: [ { name: 'Event 1', start: '2022-04-01', timed: false, }, { name: 'Event 2', start: '2022-04-04', end: '2022-04-06', }, { name: 'Event 3', start: '2022-04-04T05:00:00', end: '2022-04-04T07:00:00', timed: true, }, { name: 'Event 4', start: '2022-04-08T08:00:00', end: '2022-04-08T10:00:00', timed: true, }, ], }; }, methods: { viewDay({ date }) { this.focus = date; this.type = 'day'; }, showEvent({ nativeEvent, event }) { const open = () => { this.selectedEvent = event; this.selectedElement = nativeEvent.target; requestAnimationFrame(() => requestAnimationFrame( () => (this.selectedOpen = true) ) ); }; if (this.selectedOpen) { this.selectedOpen = false; requestAnimationFrame(() => requestAnimationFrame(() => open()) ); } else { open(); } nativeEvent.stopPropagation(); }, }, computed: { selectedEventStart() { return ( (this.selectedEvent && this.selectedEvent.start && format( new Date(this.selectedEvent.start), 'h:mm a' )) || '12:00 AM' ); }, selectedEventEnd() { return ( (this.selectedEvent && this.selectedEvent.end && format( new Date(this.selectedEvent.end), 'h:mm a' )) || '12:00 AM' ); }, }, }; </script> 

The calendar starts out in the month view. When the user clicks a day, we change the calendar to the day view:

Using the @click:day event to add interactivity to the Vuetify calendar component.

We also created a menu that will display information about an event when the user clicks it in the day or month view:

Using the @click:event event to add interactivity to the Vuetify calendar component.

Custom calendar buttons

Calendar day slot

We can use the day slot of v-calendar to customize how a day is displayed in the week or month view. In the example below, we use this slot to create a calendar that displays the percentage of a day that was used for activities of a certain category.

App.vue
<template> <v-app> <div class="ma-4" style="height: 100%" > <v-calendar :now="today" :value="today" color="primary" > <template v-slot:day="{ past, date }"> <v-row class="fill-height"> <template v-if="past && tracked[date]"> <v-sheet v-for="(percent, i) in tracked[date]" :key="i" :title="category[i]" :color="colors[i]" :width="`${percent}%`" height="100%" tile ></v-sheet> </template> </v-row> </template> </v-calendar> </div> </v-app> </template> <script> export default { name: 'App', data: () => ({ today: '2022-04-11', tracked: { '2022-04-01': [20, 45, 10], '2022-04-02': [40, 30, 0], '2022-04-03': [10, 25, 50], '2022-04-04': [25, 25, 20], '2022-04-05': [20], '2022-04-06': [20, 60, 10], '2022-04-07': [0, 0, 25], '2022-04-08': [60, 15, 20], '2022-04-09': [45, 0, 5], '2022-04-10': [30, 20, 20], }, colors: ['blue', 'yellow darken-3', 'red accent-2'], category: ['Category 1', 'Category 2', 'Category 3'], }), }; </script> 
Using the day slot of the Vuetify calendar component.

Conclusion

We can use the Vuetify calendar component (v-calendar) to create a calendar that displays events and other information for our application. This component comes with various props and slots that we can use to easily customize its appearance and behavior.

Vuetify FAB: How to Create Floating Action Buttons

A floating action button (FAB) is used to signify the primary action to be taken on a particular screen. In this post, we’re going to learn how to use the button component (v-btn) to create FABs.

v-btn fab Prop

We can create an FAB by setting the fab prop of the button component to true:

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-btn fab>
        <v-icon>mdi-plus</v-icon>
      </v-btn>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Create an FAB with the fab prop of the Vuetify button component.

Vuetify FAB Color

We can use the color prop of the v-btn component to customize the color of the FAB.

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-btn
        fab
        color="primary"
      >
        <v-icon>mdi-plus</v-icon>
      </v-btn>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Customize the color of an FAB with Vuetify.

Vuetify FAB Depressed

Setting the depressed prop of the v-btn component to true will remove elevation from an FAB.

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-btn
        fab
        color="primary"
        depressed
      >
        <v-icon>mdi-plus</v-icon>
      </v-btn>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Create a depressed FAB with Vuetify.

FAB icon Prop

The icon prop designates the button component as an icon. It removes the background and sets the FAB icon color to the value of the color prop.

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-btn
        fab
        color="primary"
        icon
      >
        <v-icon>mdi-plus</v-icon>
      </v-btn>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the icon prop to create an FAB in Vuetify.

Vuetify FAB Outlined

We can the outlined prop of the v-btn component to create an outlined FAB.

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-btn
        fab
        color="primary"
        outlined
      >
        <v-icon>mdi-plus</v-icon>
      </v-btn>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Creating an outlined FAB with Vuetify.

Vuetify FAB Elevation

We can control the amount of elevation the FAB has with the elevation prop. We can set the elevation to a value between 0 and 24 inclusive.

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-btn
        fab
        color="primary"
        elevation="10"
      >
        <v-icon>mdi-plus</v-icon>
      </v-btn>
    </div>
  </v-app>
</template>

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

Vuetify FAB Tile

The tile property removes the border-radius from the FAB:

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-btn
        fab
        color="primary"
        tile
      >
        <v-icon>mdi-plus</v-icon>
      </v-btn>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the title prop to create an FAB in Vuetify.

Vuetify FAB Size

We can use one of the x-small, small, large, and x-large props to customize the size of the FAB.

<template>
  <v-app>
    <div class="d-flex justify-center">
      <div
        class="d-flex ma-4 align-center justify-space-around"
        style="width: 400px"
      >
        <v-btn
          fab
          color="primary"
          x-small
        >
          <v-icon>mdi-plus</v-icon>
        </v-btn>
        <v-btn
          fab
          color="primary"
          small
        >
          <v-icon>mdi-plus</v-icon>
        </v-btn>
        <v-btn
          fab
          color="primary"
        >
          <v-icon>mdi-plus</v-icon>
        </v-btn>
        <v-btn
          fab
          color="primary"
          large
        >
          <v-icon>mdi-plus</v-icon>
        </v-btn>
        <v-btn
          fab
          color="primary"
          x-large
        >
          <v-icon>mdi-plus</v-icon>
        </v-btn>
      </div>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Customizing the size of an FAB in Vuetify.

Extended FAB

Vuetify doesn’t support it yet, but we can use custom CSS to create an extended FAB.

<template>
  <v-app>
    <div class="text-center ma-4">
      <v-btn
        fab
        color="primary"
        style="
          width: fit-content;
          border-radius: 100px;
          padding: 16px;
        "
      >
        <v-icon>mdi-plus</v-icon>
        Create
      </v-btn>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Creating an extended FAB in Vuetify.

Vuetify FAB Speed Dial

With the speed dial component (v-speed-dial), an FAB can emit a stack of related actions when pressed:

<template>
  <v-app>
    <v-speed-dial
      v-model="fab"
      direction="top"
      transition="slide-y-reverse-transition"
      absolute
      bottom
      right
    >
      <template v-slot:activator>
        <v-btn
          v-model="fab"
          color="blue darken-2"
          dark
          fab
        >
          <v-icon v-if="fab"> mdi-close </v-icon>
          <v-icon v-else> mdi-image </v-icon>
        </v-btn>
      </template>
      <v-btn
        fab
        small
      >
        <v-icon>mdi-pencil</v-icon>
      </v-btn>
      <v-btn
        fab
        small
      >
        <v-icon>mdi-plus</v-icon>
      </v-btn>
      <v-btn
        fab
        small
      >
        <v-icon>mdi-star</v-icon>
      </v-btn>
    </v-speed-dial>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    fab: false,
  }),
};
</script>
Using an FAB with a speed dial.

Using FABs in Lateral Screens

There are certain instances where we have FABs with different actions on screens next to each other, like the content screens of a set of tab items. We can display a transition to signify the change of action with the fab-transition component. fab-transition works with the key prop of the v-btn. It triggers the transition when the FAB key changes.

<template>
  <v-app>
    <v-app-bar
      dark
      color="red accent-2"
      app
    >
      <v-app-bar-nav-icon></v-app-bar-nav-icon>
      <v-toolbar-title>Page Title</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>
      <template v-slot:extension>
        <v-tabs
          v-model="tabs"
          align-with-title
        >
          <v-tab href="#one"> Item One </v-tab>
          <v-tab href="#two"> Item Two </v-tab>
          <v-tab href="#three"> Item Three </v-tab>
          <v-tabs-slider color="white"></v-tabs-slider>
        </v-tabs>
      </template>
    </v-app-bar>
    <v-main>
      <v-fab-transition>
        <v-btn
          :key="activeFab.icon"
          fab
          right
          absolute
          bottom
          style="bottom: 16px"
          color="red accent-2"
          dark
        >
          <v-icon>{{ activeFab.icon }}</v-icon>
        </v-btn>
      </v-fab-transition>
    </v-main>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    fab: false,
    hidden: false,
    tabs: null,
  }),

  computed: {
    activeFab() {
      switch (this.tabs) {
        case 'one':
          return {
            icon: 'mdi-plus',
          };
        case 'two':
          return { icon: 'mdi-pencil' };
        case 'three':
          return {
            icon: 'mdi-play',
          };
        default:
          return {};
      }
    },
  },
};
</script>

Using FABs in lateral screens.

Conclusion

A floating action button (FAB) is used to indicate the main action to be performed on a screen. We can use the fab prop of the v-btn component in combination with various other props to create and customize FABs.

How to Use the Vuetify Rating Component

The Vuetify rating component is useful for collecting user feedback. Users can use it to indicate their level of satisfaction with certain content. Read on to find out more about this component and the various ways in which we can customize it.

The Vuetify Rating Component (v-rating)

We use v-rating to create a rating component.

<template>
  <v-app>
    <div class="d-flex ma-2 justify-center">
      <v-rating></v-rating>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Creating a Vuetify rating component.

The user can indicate various levels of satisfaction by clicking on one of the items.

Clicking on a star of the Vuetify rating component.

Vuetify Rating Value

We use the value prop to programmatically set the number of selected items on the rating component. The default is 0.

<template>
  <v-app>
    <div class="text-center ma-2">
      <v-rating></v-rating>
      <v-rating :value="3"></v-rating>
      <v-rating :value="5"></v-rating>
    </div>
  </v-app>
</template>

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

Vuetify Rating v-model

We can use v-model to set up a two-way binding between the value of the v-rating and a variable. In the code example below, we use v-model to create a rating component with text below it displaying the current value:

<template>
  <v-app>
    <div class="d-flex ma-2 justify-center">
      <v-rating v-model="rating"></v-rating>
    </div>
    <div class="d-flex ma-2 justify-center">
      Rating: {{ rating }}
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    rating: 0,
  }),
};
</script>
Using v-model on the Vuetify rating component.

We can also use the two-way binding to add a button that changes the rating when clicked:

<template>
  <v-app>
    <div class="d-flex ma-2 justify-center">
      <v-rating v-model="rating"></v-rating>
    </div>
    <div class="d-flex ma-2 justify-center">
      Rating: {{ rating }}
    </div>
    <div class="d-flex ma-2 justify-center">
      <v-btn
        @click="rating = 5"
        color="primary"
      >
        5 stars
      </v-btn>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    rating: 0,
  }),
};
</script>
Using v-model on the Vuetify rating component.

Readonly

We can turn off interactivity with the v-rating component with the readonly prop.

<template>
  <v-app>
    <div class="text-center ma-2">
      <v-rating
        :value="3"
        readonly
      ></v-rating>
    </div>
  </v-app>
</template>

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

Vuetify Rating Colors

v-rating comes with the color and background-color props for customizing its color. We can use any color from the Material design spec.

The color prop sets the color of the selected items, while the background-color prop sets the color of the unselected items.

<template>
  <v-app>
    <div class="text-center">
      <v-rating
        v-model="rating"
        background-color="purple accent-4"
        color="purple"
      >
      </v-rating>

      <v-rating
        v-model="rating"
        background-color="primary"
        color="pink"
      >
      </v-rating>

      <v-rating
        v-model="rating"
        background-color="green"
        color="orange"
      >
      </v-rating>

      <v-rating
        v-model="rating"
        background-color="yellow darken-3"
        color="green"
      >
      </v-rating>

      <v-rating
        v-model="rating"
        background-color="red"
        color="red"
      >
      </v-rating>

      <v-rating
        v-model="rating"
        background-color="indigo"
        color="indigo"
      ></v-rating>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    rating: 3,
  }),
};
</script>
Customizing the colors of the Vuetify rating component.

Vuetify Rating Length

We can use the length prop to set the number of rating levels we want the rating component to have.

<template>
  <v-app>
    <div class="text-center ma-2">
      <v-rating
        :value="3"
        color="yellow darken-3"
        background-color="grey darken-1"
      ></v-rating>
      <v-rating
        length="6"
        :value="3"
        color="yellow darken-3"
        background-color="grey darken-1"
      ></v-rating>
      <v-rating
        length="7"
        :value="4"
        color="yellow darken-3"
        background-color="grey darken-1"
      ></v-rating>
      <v-rating
        length="8"
        :value="4"
        color="yellow darken-3"
        background-color="grey darken-1"
      ></v-rating>
      <v-rating
        length="9"
        :value="5"
        color="yellow darken-3"
        background-color="grey darken-1"
      ></v-rating>
    </div>
  </v-app>
</template>

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

Vuetify Rating Hover

Setting the hover prop makes the v-rating display visual feedback when the user hovers over it with the mouse.

<template>
  <v-app>
    <div class="text-center ma-2">
      <v-rating hover></v-rating>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    rating: 3,
  }),
};
</script>
Using the hover prop of the Vuetify rating component.

Vuetify Rating Half Increments

Use the half-increments prop to allow selection of half rating level increments.

<template>
  <v-app>
    <div class="text-center ma-2">
      <v-rating
        hover
        half-increments
        color="yellow darken-3"
        background-color="grey darken-1"
        :value="0.5"
      ></v-rating>
      <v-rating
        hover
        half-increments
        color="yellow darken-3"
        background-color="grey darken-1"
        :value="2.5"
      ></v-rating>
      <v-rating
        hover
        half-increments
        color="yellow darken-3"
        background-color="grey darken-1"
        :value="4.5"
      ></v-rating>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the half-increments prop of the Vuetify rating component.

Vuetify Rating Size

We can customize the size of the rating component with the same classes available in the icon component (v-icon).

<template>
  <v-app>
    <div class="text-center ma-2">
      <v-rating
        hover
        color="yellow darken-3"
        background-color="grey darken-1"
        :value="3"
        x-small
      ></v-rating>
      <v-rating
        hover
        color="yellow darken-3"
        background-color="grey darken-1"
        :value="3"
        small
      ></v-rating>
      <v-rating
        hover
        color="yellow darken-3"
        background-color="grey darken-1"
        :value="3"
        medium
      ></v-rating>
      <v-rating
        hover
        color="yellow darken-3"
        background-color="grey darken-1"
        :value="3"
        large
      ></v-rating>
      <v-rating
        hover
        color="yellow darken-3"
        background-color="grey darken-1"
        :value="3"
        x-large
      ></v-rating>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Setting the size of the v-rating component.

We can also customize the size by setting the size prop to a numerical value:

<template>
  <v-app>
    <div class="text-center ma-2">
      <v-rating
        hover
        color="yellow darken-3"
        background-color="grey darken-1"
        :value="3"
        v-for="num in 5"
        :key="num"
        :size="num * 10"
      ></v-rating>
    </div>
  </v-app>
</template>

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

Item Slot

v-rating comes with an item slot that we can use to apply a greater amount of customization.

<template>
  <v-app>
    <div class="text-center ma-2">
      <v-rating v-model="rating">
        <template v-slot:item="props">
          <v-icon
            :color="
              props.isFilled
                ? getColor(props.index)
                : 'grey lighten-1'
            "
            large
            @click="props.click"
          >
            {{
              props.isFilled
                ? 'mdi-star-circle'
                : 'mdi-star-circle-outline'
            }}
          </v-icon>
        </template>
      </v-rating>
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    colors: [
      'primary',
      'yellow darken-3',
      'red',
      'purple accent-4',
      'indigo',
    ],
    rating: 4,
  }),
  methods: {
    getColor(index) {
      return this.colors[index];
    },
  },
};
</script>
Using the item slot of the Vuetify rating component.

Conclusion

We can use the Vuetify rating component (v-rating) in our application to collect user feedback. This component comes with various props and slots that allow customization.

How to Use the Vuetify Bottom Navigation Component

A bottom navigation bar is an alternative to a sidebar or navigation drawer. It is used mainly in mobile applications and enables quick navigation to the top-level destinations of an app. In this article, we’re going to learn about the Vuetify bottom navigation component and how we can use it to easily create and customize bottom navigation bars.

The Vuetify Bottom Navigation Component (v-bottom-navigation)

Vuetify provides the v-bottom-navigation component for creating bottom navigation bars. It includes a set of v-btns for navigation. We can use the value prop of v-bottom-navigation to set the currently active button programmatically. The button with a matching value prop will be made active. By default, the value of each button is set to its zero-based index in the set of buttons on the bottom navigation bar, i.e., the first button has its value set to 0, the second button to 1, the third to 2, and so on. But we can set a custom value to the value prop of a v-btn to change this.

<template>
  <v-app>
    <v-app-bar
      color="primary"
      app
      dark
    >
      <v-toolbar-title>App Bar</v-toolbar-title>
    </v-app-bar>
    <v-main>
      <v-container
        >Lorem ipsum dolor sit amet consectetur adipisicing
        elit. Quis blanditiis beatae praesentium repudiandae
        sunt officiis, vero maxime officia obcaecati nisi
        excepturi. Sit laboriosam provident laborum? Rem
        recusandae ea possimus illo.</v-container
      >
    </v-main>
    <v-bottom-navigation
      v-model="value"
      app
    >
      <v-btn
        value="music"
        height="100%"
      >
        <span>Music</span>
        <v-icon>mdi-music</v-icon>
      </v-btn>

      <v-btn
        value="books"
        height="100%"
      >
        <span>Books</span>
        <v-icon>mdi-book</v-icon>
      </v-btn>

      <v-btn
        value="photos"
        height="100%"
      >
        <span>Photos</span>
        <v-icon>mdi-image</v-icon>
      </v-btn>
    </v-bottom-navigation>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({ value: 'music' }),
};
</script>
Using the Vuetify bottom navigation component.

Vuetify Bottom Navigation Color

We can use the color prop of v-bottom-navigation to set the color of the active button on the bottom navigation bar. We can use any color from the Material Design specs.

<template>
  <v-app>
    <v-app-bar
      color="primary"
      app
      dark
    >
      <v-toolbar-title>App Bar</v-toolbar-title>
    </v-app-bar>
    <v-main>
      <v-container
        >Lorem ipsum dolor sit amet consectetur adipisicing
        elit. Quis blanditiis beatae praesentium repudiandae
        sunt officiis, vero maxime officia obcaecati nisi
        excepturi. Sit laboriosam provident laborum? Rem
        recusandae ea possimus illo.</v-container
      >
    </v-main>
    <v-bottom-navigation
      v-model="value"
      app
      color="primary"
    >
      <v-btn
        value="music"
        height="100%"
      >
        <span>Music</span>
        <v-icon>mdi-music</v-icon>
      </v-btn>

      <v-btn
        value="books"
        height="100%"
      >
        <span>Books</span>
        <v-icon>mdi-book</v-icon>
      </v-btn>

      <v-btn
        value="photos"
        height="100%"
      >
        <span>Photos</span>
        <v-icon>mdi-image</v-icon>
      </v-btn>
    </v-bottom-navigation>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({ value: 'music' }),
};
</script>
Customizing the color of the Vuetify bottom navigation component.

Background Color

Use the background-color prop to set the background color of the bottom navigation bar.

<template>
  <v-app>
    <v-app-bar
      :color="color"
      app
      dark
    >
      <v-toolbar-title>App Bar</v-toolbar-title>
    </v-app-bar>
    <v-main>
      <v-container
        >Lorem ipsum dolor sit amet consectetur adipisicing
        elit. Quis blanditiis beatae praesentium repudiandae
        sunt officiis, vero maxime officia obcaecati nisi
        excepturi. Sit laboriosam provident laborum? Rem
        recusandae ea possimus illo.</v-container
      >
    </v-main>
    <v-bottom-navigation
      v-model="value"
      app
      :background-color="color"
      dark
    >
      <v-btn
        value="music"
        height="100%"
        :color="color"
      >
        <span>Music</span>
        <v-icon>mdi-music</v-icon>
      </v-btn>

      <v-btn
        value="books"
        height="100%"
        :color="color"
      >
        <span>Books</span>
        <v-icon>mdi-book</v-icon>
      </v-btn>

      <v-btn
        value="photos"
        height="100%"
        :color="color"
      >
        <span>Photos</span>
        <v-icon>mdi-image</v-icon>
      </v-btn>
    </v-bottom-navigation>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 'music',
    color: 'purple accent-4',
  }),
};
</script>
Customizing the background color of the Vuetify bottom navigation component.

v-model

We can use v-model to set up a two-way binding between the currently active button and a variable. In the code example below, we change the title of the app bar to the text of the button that becomes active when clicked.

<template>
  <v-app>
    <v-app-bar
      :color="color"
      app
      dark
    >
      <v-toolbar-title>
        {{ capitalize(value) }}
      </v-toolbar-title>
    </v-app-bar>
    <v-main>
      <v-container
        >Lorem ipsum dolor sit amet consectetur adipisicing
        elit. Quis blanditiis beatae praesentium repudiandae
        sunt officiis, vero maxime officia obcaecati nisi
        excepturi. Sit laboriosam provident laborum? Rem
        recusandae ea possimus illo.</v-container
      >
    </v-main>
    <v-bottom-navigation
      v-model="value"
      app
      :background-color="color"
      dark
    >
      <v-btn
        value="music"
        height="100%"
        :color="color"
      >
        <span>Music</span>
        <v-icon>mdi-music</v-icon>
      </v-btn>

      <v-btn
        value="books"
        height="100%"
        :color="color"
      >
        <span>Books</span>
        <v-icon>mdi-book</v-icon>
      </v-btn>

      <v-btn
        value="photos"
        height="100%"
        :color="color"
      >
        <span>Photos</span>
        <v-icon>mdi-image</v-icon>
      </v-btn>
    </v-bottom-navigation>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 'music',
    color: 'green',
  }),
  methods: {
    capitalize(str) {
      return str.charAt(0).toUpperCase() + str.slice(1);
    },
  },
};
</script>
Using v-model on the Vuetify bottom navigation component.

Vuetify Bottom Navigation Grow

We can set the grow prop to true on the v-bottom-navigation to force the v-btn components to fill all the available space. The buttons can have a maximum width of 168px, according to the Bottom Navigation Material Design specs.

<template>
  <v-app>
    <v-app-bar
      :color="color"
      app
      dark
    >
      <v-toolbar-title> App Bar </v-toolbar-title>
    </v-app-bar>
    <v-main>
      <v-container
        >Lorem ipsum dolor sit amet consectetur adipisicing
        elit. Quis blanditiis beatae praesentium repudiandae
        sunt officiis, vero maxime officia obcaecati nisi
        excepturi. Sit laboriosam provident laborum? Rem
        recusandae ea possimus illo.</v-container
      >
    </v-main>
    <v-bottom-navigation
      v-model="value"
      app
      :background-color="color"
      dark
      grow
    >
      <v-btn
        value="music"
        height="100%"
        :color="color"
      >
        <span>Music</span>
        <v-icon>mdi-music</v-icon>
      </v-btn>

      <v-btn
        value="books"
        height="100%"
        :color="color"
      >
        <span>Books</span>
        <v-icon>mdi-book</v-icon>
      </v-btn>

      <v-btn
        value="photos"
        height="100%"
        :color="color"
      >
        <span>Photos</span>
        <v-icon>mdi-image</v-icon>
      </v-btn>
    </v-bottom-navigation>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 'music',
    color: 'green',
  }),
};
</script>
Using the grow prop of the Vuetify bottom navigation component.

Vuetify Bottom Navigation Hide on Scroll

The hide-on-scroll prop hides the bottom navigation bar when scrolling up, and displays it when scrolling down. This is similar to the scrolling techniques supported by the v-app-bar component.

<template>
  <v-app>
    <v-app-bar
      :color="color"
      app
      dark
    >
      <v-toolbar-title> App Bar </v-toolbar-title>
    </v-app-bar>
    <v-main>
      <v-responsive
        max-height="600"
        id="hide-on-scroll-example"
        class="overflow-y-auto"
      >
        <v-responsive
          height="1500"
          class="ma-4"
        >
          Lorem ipsum dolor sit amet consectetur adipisicing
          elit. Quis blanditiis beatae praesentium
          repudiandae sunt officiis, vero maxime officia
          obcaecati nisi excepturi. Sit laboriosam provident
          laborum? Rem recusandae ea possimus illo.
        </v-responsive>
      </v-responsive>
    </v-main>
    <v-bottom-navigation
      v-model="value"
      app
      :background-color="color"
      dark
      hide-on-scroll
      scroll-target="#hide-on-scroll-example"
    >
      <v-btn
        value="music"
        height="100%"
        :color="color"
      >
        <span>Music</span>
        <v-icon>mdi-music</v-icon>
      </v-btn>

      <v-btn
        value="books"
        height="100%"
        :color="color"
      >
        <span>Books</span>
        <v-icon>mdi-book</v-icon>
      </v-btn>

      <v-btn
        value="photos"
        height="100%"
        :color="color"
      >
        <span>Photos</span>
        <v-icon>mdi-image</v-icon>
      </v-btn>
    </v-bottom-navigation>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 'music',
    color: 'indigo',
  }),
};
</script>
Using the hide-on-scroll prop of the Vuetify bottom navigation component.

Vuetify Bottom Navigation Scroll Threshold

The scroll-threshold prop sets the distance a user must scroll up to before the bottom navigation bar is hidden. For example, setting scroll-treshold to 0 means the v-bottom-navigation will only get hidden when the user scrolls up to the very top of the page:

<template>
  <v-app>
    <v-app-bar
      :color="color"
      app
      dark
    >
      <v-toolbar-title> App Bar </v-toolbar-title>
    </v-app-bar>
    <v-main>
      <v-responsive
        max-height="600"
        id="hide-on-scroll-example"
        class="overflow-y-auto"
      >
        <v-responsive
          height="1500"
          class="ma-4"
        >
          Lorem ipsum dolor sit amet consectetur adipisicing
          elit. Quis blanditiis beatae praesentium
          repudiandae sunt officiis, vero maxime officia
          obcaecati nisi excepturi. Sit laboriosam provident
          laborum? Rem recusandae ea possimus illo.
        </v-responsive>
      </v-responsive>
    </v-main>
    <v-bottom-navigation
      v-model="value"
      app
      :background-color="color"
      dark
      hide-on-scroll
      scroll-target="#hide-on-scroll-example"
      scroll-threshold="0"
    >
      <v-btn
        value="music"
        height="100%"
        :color="color"
      >
        <span>Music</span>
        <v-icon>mdi-music</v-icon>
      </v-btn>

      <v-btn
        value="books"
        height="100%"
        :color="color"
      >
        <span>Books</span>
        <v-icon>mdi-book</v-icon>
      </v-btn>

      <v-btn
        value="photos"
        height="100%"
        :color="color"
      >
        <span>Photos</span>
        <v-icon>mdi-image</v-icon>
      </v-btn>
    </v-bottom-navigation>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 'music',
    color: 'indigo',
  }),
};
</script>
Using the scroll-threshold prop of the Vuetify bottom navigation component.

Vuetify Bottom Navigation Horizontal

With the horizontal prop, we can position the button text inline with the provided v-icon.

<template>
  <v-app>
    <v-app-bar
      :color="color"
      app
      dark
    >
      <v-toolbar-title> App Bar </v-toolbar-title>
    </v-app-bar>
    <v-main>
      <v-container>
        Lorem ipsum dolor sit amet consectetur adipisicing
        elit. Quis blanditiis beatae praesentium repudiandae
        sunt officiis, vero maxime officia obcaecati nisi
        excepturi. Sit laboriosam provident laborum? Rem
        recusandae ea possimus illo.
      </v-container>
    </v-main>
    <v-bottom-navigation
      v-model="value"
      app
      :background-color="color"
      dark
      horizontal
    >
      <v-btn
        value="music"
        height="100%"
        :color="color"
      >
        <span>Music</span>
        <v-icon>mdi-music</v-icon>
      </v-btn>

      <v-btn
        value="books"
        height="100%"
        :color="color"
      >
        <span>Books</span>
        <v-icon>mdi-book</v-icon>
      </v-btn>

      <v-btn
        value="photos"
        height="100%"
        :color="color"
      >
        <span>Photos</span>
        <v-icon>mdi-image</v-icon>
      </v-btn>
    </v-bottom-navigation>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 'music',
    color: 'primary',
  }),
};
</script>
Using the horizontal prop of the Vuetify bottom navigation component.

Vuetify Bottom Navigation Shift

We can the shift prop to hide the text of the navigation bar buttons that are not active.

<template>
  <v-app>
    <v-app-bar
      :color="color"
      app
      dark
    >
      <v-toolbar-title> App Bar </v-toolbar-title>
    </v-app-bar>
    <v-main>
      <v-container>
        Lorem ipsum dolor sit amet consectetur adipisicing
        elit. Quis blanditiis beatae praesentium repudiandae
        sunt officiis, vero maxime officia obcaecati nisi
        excepturi. Sit laboriosam provident laborum? Rem
        recusandae ea possimus illo.
      </v-container>
    </v-main>
    <v-bottom-navigation
      v-model="value"
      app
      :background-color="color"
      dark
      shift
    >
      <v-btn
        value="music"
        height="100%"
        :color="color"
      >
        <span>Music</span>
        <v-icon>mdi-music</v-icon>
      </v-btn>

      <v-btn
        value="books"
        height="100%"
        :color="color"
      >
        <span>Books</span>
        <v-icon>mdi-book</v-icon>
      </v-btn>

      <v-btn
        value="photos"
        height="100%"
        :color="color"
      >
        <span>Photos</span>
        <v-icon>mdi-image</v-icon>
      </v-btn>
    </v-bottom-navigation>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 'music',
    color: 'primary',
  }),
};
</script>
Using the shift prop of the Vuetify bottom navigation component.

Vuetify Bottom Navigation Toggle

We can use the input-value prop of v-bottom-navigation to toggle the visibility of the bottom navigation bar:

<template>
  <v-app>
    <v-app-bar
      :color="color"
      app
      dark
    >
      <v-toolbar-title> App Bar </v-toolbar-title>
    </v-app-bar>
    <v-main>
      <v-container>
        Lorem ipsum dolor sit amet consectetur adipisicing
        elit. Quis blanditiis beatae praesentium repudiandae
        sunt officiis, vero maxime officia obcaecati nisi
        excepturi. Sit laboriosam provident laborum? Rem
        recusandae ea possimus illo.
        <v-row justify="center">
          <v-btn
            class="ma-8"
            outlined
            :color="color"
            @click="active = !active"
          >
            Toggle Navigation
          </v-btn>
        </v-row>
      </v-container>
    </v-main>
    <v-bottom-navigation
      v-model="value"
      app
      :background-color="color"
      dark
      :input-value="active"
    >
      <v-btn
        value="music"
        height="100%"
        :color="color"
      >
        <span>Music</span>
        <v-icon>mdi-music</v-icon>
      </v-btn>

      <v-btn
        value="books"
        height="100%"
        :color="color"
      >
        <span>Books</span>
        <v-icon>mdi-book</v-icon>
      </v-btn>

      <v-btn
        value="photos"
        height="100%"
        :color="color"
      >
        <span>Photos</span>
        <v-icon>mdi-image</v-icon>
      </v-btn>
    </v-bottom-navigation>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    value: 'music',
    color: 'purple accent-4',
    active: true,
  }),
};
</script>
Using the input-value prop of the Vuetify bottom navigation component.

Conclusion

We can use a bottom navigation bar in place of a sidebar or navigation drawer for quick and easy navigation to important destinations in our app. Vuetify provides the bottom navigation component (v-bottom-navigation) for creating bottom navigation bars.

How to Use the Vuetify Banner Component

We can use a banner to display a message to the user with one or two related actions. It can be single-line or multi-line and can contain icons that fit in with the message and actions. Read on to find out more on how to create and customize banners with the Vuetify banner component.

The Vuetify Banner Component (v-banner)

We can use the v-banner component from Vuetify to create a banner. It is multi-line by default.

<template>
  <v-app>
    <v-banner>
      Lorem ipsum dolor sit amet consectetur adipisicing
      elit. A necessitatibus dicta voluptatibus, recusandae
      exercitationem, consequuntur asperiores deleniti ut
      sequi officia animi architecto.
    </v-banner>
  </v-app>
</template>

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

Single Line Banner

Use the single-line prop on a v-banner to make the message on the banner occupy only one line. It will be truncated with an ellipsis if it’s too long.

<template>
  <v-app>
    <v-banner single-line>
      Lorem ipsum dolor sit amet consectetur adipisicing
      elit. A necessitatibus dicta voluptatibus, recusandae
      exercitationem, consequuntur asperiores deleniti ut
      sequi officia animi architecto.
    </v-banner>
  </v-app>
</template>

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

Vuetify Banner Color

Vuetify allows us to customize the color of the v-banner component with the color prop. We can use any color from the Material Design spec.

<template>
  <v-app>
    <v-banner
      color="primary"
      dark
      class="ma-4"
    >
      Lorem ipsum dolor sit amet consectetur adipisicing
      elit. A necessitatibus dicta voluptatibus, recusandae
      exercitationem, consequuntur asperiores deleniti ut
      sequi officia animi architecto.
    </v-banner>
  </v-app>
</template>

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

Vuetify Banner Sticky

The sticky prop sets the position CSS property of the banner element to sticky.

<template>
  <v-app>
    <div
      style="max-height: 400px"
      class="overflow-y-auto"
    >
      <v-banner
        sticky
        color="white"
      >
        Sticky banner
      </v-banner>
      Lorem ipsum dolor sit amet, consectetur adipisicing
      elit. Dicta voluptatibus maxime ullam cum quasi ad
      placeat qui ipsa odit quam sit nemo, laborum fuga enim
      saepe dolorum ex aperiam tempora? Lorem ipsum dolor
      sit amet consectetur adipisicing elit. Quasi iste
      earum nihil? Distinctio natus in cumque tempora veniam
      placeat consectetur, consequatur recusandae quaerat
      qui impedit ea cum, perferendis ipsum excepturi. Lorem
      ipsum dolor sit amet consectetur adipisicing elit.
      Libero impedit quo doloremque perferendis odit
      consequuntur maxime iure sint vel autem ipsa, eveniet
      dolore exercitationem, perspiciatis porro numquam
      earum laudantium laborum. Lorem, ipsum dolor sit amet
      consectetur adipisicing elit. Totam ducimus laborum
      suscipit distinctio tempore alias quos quasi eius
      praesentium itaque quas error fugit numquam, beatae
      sint dolor quis, officiis dignissimos. Lorem ipsum
      dolor sit amet consectetur adipisicing elit. Quas
      aliquid quia fugiat repudiandae ea, autem commodi
      praesentium obcaecati, corrupti sed ipsum dolores
      illum sit cum, officiis esse! Culpa, temporibus minus!
      Lorem ipsum dolor sit amet consectetur adipisicing
      elit. Sint placeat animi omnis nemo possimus quam
      optio earum ut amet aspernatur, consectetur nesciunt
      rem. Earum exercitationem, tempora blanditiis tenetur
      nemo magnam. Lorem ipsum dolor sit amet consectetur
      adipisicing elit. Nulla quisquam possimus officia,
      doloremque dolorum facere perspiciatis eaque rem
      quibusdam pariatur, laborum quod similique eius
      eligendi vero dicta ipsam iusto amet! Lorem ipsum
      dolor sit amet consectetur adipisicing elit. Pariatur
      ad labore doloribus voluptatem esse necessitatibus
      totam eaque fugit. Libero dolore autem totam sed
      possimus iure aspernatur dolorum voluptate odit
      laborum? Lorem ipsum dolor sit amet consectetur
      adipisicing elit. Quidem distinctio necessitatibus
      optio, quos id sint eius cupiditate. Itaque ipsum
      atque ad hic officiis vero earum, voluptatum debitis
      consectetur dolore unde. Lorem ipsum dolor sit amet
      consectetur, adipisicing elit. Eaque ullam cumque
      quasi unde illum, dolorem vel vero veritatis magnam
      consequatur commodi consectetur architecto dicta
      expedita ducimus officiis facilis sed ab. Lorem ipsum
      dolor sit, amet consectetur adipisicing elit. Minima
      veritatis neque quaerat fuga qui iste consectetur, in
      ab facilis quia laudantium voluptatum iusto ratione
      aliquid necessitatibus ipsam aspernatur sit
      dignissimos. Lorem ipsum dolor sit amet consectetur
      adipisicing elit. A ipsa pariatur modi, exercitationem
      minus quo dolorem reiciendis deserunt iste quod
      provident porro praesentium at sequi laboriosam qui
      cum saepe sint. Lorem, ipsum dolor sit amet
      consectetur adipisicing elit. Eum ab obcaecati
      perferendis. Deleniti modi eaque saepe inventore, a
      non officia ut quisquam illo fuga natus temporibus.
      Aliquid ab veritatis eius? Lorem ipsum dolor sit amet
      consectetur adipisicing elit. Sed ipsam iste laborum
      minima debitis modi corrupti, eos obcaecati aut magni,
      quod earum quaerat nobis esse eveniet omnis eligendi
      aspernatur voluptate! Lorem ipsum dolor sit amet
      consectetur, adipisicing elit. Nesciunt facilis fuga
      quas sed autem eligendi rerum dolorem optio. Nulla
      obcaecati veniam sunt ipsa exercitationem reiciendis
      totam dolorem tenetur fuga provident. Lorem ipsum
      dolor sit amet consectetur adipisicing elit.
      Temporibus ratione magni ipsam iure minima modi
      obcaecati nihil tempora debitis, quaerat corporis
      ipsum assumenda maiores nisi laboriosam doloremque.
      Ab, sapiente fuga! Lorem, ipsum dolor sit amet
      consectetur adipisicing elit. Tempore non voluptate
      quisquam quod, aliquam sequi maiores dolorum minima
      dolorem! Distinctio autem quaerat accusamus iusto
      beatae laudantium dicta omnis cum fuga. Lorem ipsum
      dolor sit amet, consectetur adipisicing elit. Quas,
      aspernatur sint maxime officiis cumque inventore, amet
      illum, soluta eum necessitatibus iure deleniti natus
      aut deserunt vitae vel facilis quod voluptatem.
    </div>
  </v-app>
</template>

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

Vuetify Banner Outlined

We can add an outline to a banner with the outlined prop:

<template>
  <v-app>
    <v-banner
      outlined
      class="ma-4"
      >Lorem ipsum dolor sit amet consectetur adipisicing
      elit.
    </v-banner>
  </v-app>
</template>

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

Rounded Banner

Setting the rounded prop to true on a v-banner makes the corners rounded.

<template>
  <v-app>
    <v-banner
      rounded
      color="green"
      dark
      class="ma-4"
    >
      Lorem ipsum dolor sit amet consectetur adipisicing
      elit.
    </v-banner>
  </v-app>
</template>

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

Vuetify Banner Shaped

The shaped prop adds a border-radius on the top-left and bottom-right corners of the banner.

<template>
  <v-app
    ><v-banner
      color="purple accent-4"
      class="ma-4"
      dark
      shaped
    >
      Lorem ipsum dolor, sit amet consectetur adipisicing
      elit.
    </v-banner>
  </v-app>
</template>

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

Vuetify Banner Tile

The tile prop removes the border-radius from the v-banner:

<template>
  <v-app>
    <v-banner
      color="primary"
      class="ma-4"
      dark
      tile
      >Lorem ipsum dolor sit amet consectetur adipisicing
      elit.
    </v-banner>
  </v-app>
</template>

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

We can add elevation to the banner component with the elevation prop.

<template>
  <v-app>
    <v-banner
      class="ma-4"
      elevation="10"
    >
      Lorem ipsum dolor sit amet consectetur adipisicing
      elit.
    </v-banner>
  </v-app>
</template>

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

Icon Slot

The banner component comes with an icon slot for including an icon on it:

<template>
  <v-app>
    <v-banner
      single-line
      class="ma-4"
      elevation="2"
      rounded
    >
      <v-icon
        slot="icon"
        color="info"
        size="36"
      >
        mdi-information
      </v-icon>
      Lorem ipsum dolor sit, amet consectetur adipisicing
      elit.
    </v-banner>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the icon slot of the Vuetify banner component.

Icon Click

We can attach a handler to the @click:icon event of v-banner to perform an action when the user clicks the banner icon.

<template>
  <v-app>
    <v-banner
      single-line
      @click:icon="iconClicked = true"
      class="ma-4"
      elevation="2"
      rounded
    >
      <v-icon
        slot="icon"
        color="info"
        size="36"
      >
        mdi-information
      </v-icon>
      Lorem ipsum dolor sit, amet consectetur adipisicing
      elit.
    </v-banner>
    <div
      v-if="iconClicked"
      class="d-flex justify-center"
    >
      Icon clicked.
    </div>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  data: () => ({
    iconClicked: false,
  }),
};
</script>
Using the @click:icon event of the v-banner component.

Vuetify Banner Action Slot

v-banner also comes with an actions slot that we can use display actions on the banner that the user can take. We use it to place functional buttons on the banner.

<template>
  <v-app>
    <v-banner
      single-line
      class="ma-4"
      elevation="2"
      rounded
    >
      <v-icon
        slot="icon"
        color="info"
        size="36"
      >
        mdi-information
      </v-icon>
      Lorem ipsum dolor sit, amet consectetur adipisicing
      elit.
      <template v-slot:actions>
        <v-btn
          color="primary"
          text
          >Action</v-btn
        >
      </template>
    </v-banner>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
Using the action slot of the Vuetify banner component.

The actions slot has a dismiss function in its scope that we can use to hide the banner.

<template>
  <v-app>
    <v-banner
      single-line
      class="ma-4"
      elevation="2"
      color="red"
      rounded
      dark
    >
      No internet connection

      <template v-slot:actions="{ dismiss }">
        <v-btn
          text
          @click="dismiss"
        >
          Dismiss
        </v-btn>

        <v-btn text>Retry</v-btn>
      </template>
    </v-banner>

  </v-app>
</template>
<script>
export default {
  name: 'App',
};
</script>
Using the dismiss slot prop of the v-banner component.

Conclusion

A banner can be used to display messages to the user with one or two actions. We can use the Vuetify banner component (v-banner) to create banners. This component comes with various props and slots for customizing its appearance and behaviour.

Vuetify v-app: How to Use v-app and v-main

One of the first components you encounter when first getting started with Vuetify is v-app. The Vuetify v-app component is required for all applications created with Vuetify. It enables many of the functionality that Vuetify provides. With v-app, child components can access global data from Vuetify, like the application theme colors or the theme variant (light/dark). v-app also ensures proper cross-browser compatibility, such as support for certain click events in browsers like Safari. We can use the app prop on other components like v-navigation-drawer, v-app-bar and v-footer and more, to help set up our application with proper sizing around the v-main component. This way, we can focus on building our application without needing to manually manage layout sizing.

Vuetify Application Markup with v-app and v-main

Thanks to automatic layout sizing, we can place our major layout elements anywhere in our markup, as long we set the app prop to true. The v-main component is important for making our page content work properly with our layout elements. v-main will be dynamically sized based on the structure of layout elements that have the app prop applied.

Here’s an example of typical Vuetify application markup:

<!-- App.vue -->

<v-app>
  <v-navigation-drawer app>
    <!-- -->
  </v-navigation-drawer>

  <v-app-bar app>
    <!-- -->
  </v-app-bar>

  <!-- Sizes your content based upon application components -->
  <v-main>

    <!-- Provides the application the proper gutter -->
    <v-container fluid>

      <!-- If using vue-router -->
      <router-view></router-view>
    </v-container>
  </v-main>

  <v-footer app>
    <!-- -->
  </v-footer>
</v-app>

Note: Applying the app prop automatically applies sets the position CSS property of the element to fixed. If we want absolute positioning, you can overwrite this functionality with the absolute prop.

Vuetify Application Components

Here is the list of all the Vuetify components that support automatic layout sizing with the app prop:

  • v-app-bar: The app bar component is always placed at the top of an application with a lower priority than v-system-bar.
  • v-bottom-navigation: The bottom navigation component is always placed at the bottom of an application with a higher priority than v-footer.
  • v-footer: The footer component is always placed at the bottom of an application with a lower priority than v-bottom-navigation.
  • v-navigation-drawer: The navigation drawer component can be placed on the left or right side of an application and can be configured to sit next to or below v-app-bar
  • v-system-bar: The system bar component is always placed at the top of an application with a higher priority than v-app.
Layout placement of the Vuetify application components.
Layout placement of the Vuetify application components.

Vuetify Application Service

We can configure our layout with the Vuetify application service. The service communicates with the v-main component so that it’s able to properly size the application content. It comes with a number of accessible properties:

{
  bar: number
  bottom: number
  footer: number
  insetFooter: number
  left: number
  right: number
  top: number
}

These properties are readonly, so we can’t edit them. We can access them from the application property of the $vuetify object. The service uses them for the layout sizing of our main content and automatically updates them when we add or remove one of the application components with the app prop applied. For example, the top property changes when v-app-bar is added or removed from the markup:

With v-app-bar:

<template>
  <v-app>
    <v-app-bar
      color="primary"
      app
    ></v-app-bar>
    <v-main>
      $vuetify.application.top:
      {{ this.$vuetify.application.top }}
    </v-main>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
The Vuetify application service updates the top property to accommodate the app bar.

Without v-app-bar:

<template>
  <v-app>
    <v-main>
      <div class="ma-4">
        $vuetify.application.top:
        {{ this.$vuetify.application.top }}
      </div>
    </v-main>
  </v-app>
</template>

<script>
export default {
  name: 'App',
};
</script>
The Vuetify app service has the top property set to 0 with no v-app-bar.

Conclusion

The Vuetify v-app component is an essential component and required in all applications made with the framework. It provides features such as automatic layout sizing, theming functionality and cross-browser compatibility.