Skip to content
Search

Vuetify

lastmod 2025-02-14created 2018-07-1263 edits

Vuetify Packages (list)

  • Vuetify.js
  • $vuetify
  • internationalization
  • v-alert
  • v-app
  • v-app-bar
  • v-app-bar-nav-icon
  • v-app-bar-title
  • v-autocomplete
  • v-avatar
  • v-badge
  • v-banner
  • v-bottom-navigation
  • v-bottom-sheet
  • v-breadcrumbs
  • v-breadcrumbs-divider
  • v-breadcrumbs-item
  • v-btn
  • v-btn-toggle
  • v-calendar
  • v-calendar-daily
  • v-calendar-monthly
  • v-calendar-weekly
  • v-card
  • v-card-actions
  • v-card-subtitle
  • v-card-text
  • v-card-title
  • v-carousel
  • v-carousel-item
  • v-carousel-reverse-transition
  • v-carousel-transition
  • v-checkbox
  • v-chip
  • v-chip-group
  • v-click-outside
  • v-col
  • v-color-picker
  • v-combobox
  • v-container
  • v-content
  • v-data-footer
  • v-data-iterator
  • v-data-table
  • v-data-table-header
  • v-date-picker
  • v-dialog
  • v-dialog-bottom-transition
  • v-dialog-top-transition
  • v-dialog-transition
  • v-divider
  • v-edit-dialog
  • v-expand-transition
  • v-expand-x-transition
  • v-expansion-panel
  • v-expansion-panel-content
  • v-expansion-panel-header
  • v-expansion-panels
  • v-fab-transition
  • v-fade-transition
  • v-file-input
  • v-flex
  • v-footer
  • v-form
  • v-hover
  • v-icon
  • v-img
  • v-input
  • v-intersect
  • v-item
  • v-item-group
  • v-layout
  • v-lazy
  • v-list
  • v-list-group
  • v-list-item
  • v-list-item-action
  • v-list-item-action-text
  • v-list-item-avatar
  • v-list-item-content
  • v-list-item-group
  • v-list-item-icon
  • v-list-item-subtitle
  • v-list-item-title
  • v-main
  • v-menu
  • v-menu-transition
  • v-mutate
  • v-navigation-drawer
  • v-overflow-btn
  • v-overlay
  • v-pagination
  • v-parallax
  • v-progress-circular
  • v-progress-linear
  • v-radio
  • v-radio-group
  • v-range-slider
  • v-rating
  • v-resize
  • v-responsive
  • v-ripple
  • v-row
  • v-scale-transition
  • v-scroll
  • v-scroll-x-reverse-transition
  • v-scroll-x-transition
  • v-scroll-y-reverse-transition
  • v-scroll-y-transition
  • v-select
  • v-sheet
  • v-simple-checkbox
  • v-simple-table
  • v-skeleton-loader
  • v-slide-group
  • v-slide-item
  • v-slide-x-reverse-transition
  • v-slide-x-transition
  • v-slide-y-reverse-transition
  • v-slide-y-transition
  • v-slider
  • v-snackbar
  • v-spacer
  • v-sparkline
  • v-speed-dial
  • v-stepper
  • v-stepper-content
  • v-stepper-header
  • v-stepper-items
  • v-stepper-step
  • v-subheader
  • v-switch
  • v-system-bar
  • v-tab
  • v-tab-item
  • v-tab-reverse-transition
  • v-tab-transition
  • v-tabs
  • v-tabs-items
  • v-tabs-slider
  • v-text-field
  • v-textarea
  • v-theme-provider
  • v-time-picker
  • v-timeline
  • v-timeline-item
  • v-toolbar
  • v-toolbar-items
  • v-toolbar-title
  • v-tooltip
  • v-touch
  • v-treeview
  • v-virtual-scroll
  • v-window
  • v-window-item

Material Component Framework for Vue.js 2

Categories

Dark theme

The default is the light theme, and you can change it by adding the dark property.

// src/plugins/vuetify.js

import Vue from 'vue'
import Vuetify from 'vuetify/lib'

Vue.use(Vuetify)

export default new Vuetify({
  theme: { dark: true },
})

Presets

You can add them with the following commands.

  • vue add vuetify-preset-basil
  • vue add vuetify-preset-crane
  • vue add vuetify-preset-fortnightly
  • vue add vuetify-preset-owl
  • vue add vuetify-preset-rally
  • vue add vuetify-preset-reply
  • vue add vuetify-preset-shrine

Preparing for TypeScript coding

Apply Vue#Preparing for TypeScript coding first.

Fixing component import errors

When importing like this

import VForm from 'vuetify/lib/components/VForm';

if you get the following error:

TS7016: Could not find a declaration file for module 'vuetify/lib/components/VForm'. '/home/your/Project/answer-plugin-vms/fe/node_modules/vuetify/lib/components/VForm/index.js' implicitly has an 'any' type.   If the 'vuetify' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module 'vuetify/lib/components/VForm';`

you need to add "noImplicitAny": false to the compiler options in tsconfig.json.

{
  "compilerOptions": {
    "skipLibCheck": true,
    "noImplicitAny": false,
    "typeRoots": [
      "node_modules/@types",
      "node_modules/vuetify/types"
    ],
    "types": ["vuetify"]
  }
}

Layouts

Vuetify has two primary layout components: v-app and v-main. The v-app component is the root of your application and directly replaces the default Vue entry point, <div id="app">. The v-main component is a semantic replacement for the main HTML element and the root of your application's content. When Vue mounts to the DOM, any Vuetify component that is part of the layout registers its current height and/or width with the framework core. The v-main component then takes these values and adjusts its container size.

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

  <v-main>
    <v-container>
      Hello World
    </v-container>
  </v-main>
</v-app>

Centering horizontally and vertically on the screen

<template>
  <v-main>

    <!-- The card in the center of the screen. -->
    <v-container fluid class="fill-height">
      <v-row align="center" justify="center">
        <v-col class="max-content-width">

          <!-- Main Content -->
          <v-card>
              <!-- ... -->
          </v-card>

        </v-col>
      </v-row>
    </v-container>

  </v-main>
</template>

<style lang="scss" scoped>
.max-content-width {
  max-width: 480px;
}
</style>

The main content is then given a maximum width of 480px.

Customizing item-text

You can use it as an element of item as follows.

:item-text="text"

According to the manual:

item-text tye can be: string | array | function

So you can also add it as a lambda, like this.

methods: {
  text: item => item.name + ' — ' + item.description
}

How to draw an SVG path directly

When you download a package such as @mdi/js, it is drawn using the v-icon component; if you draw the component yourself, do it as follows.

<template>
          <svg class="grid-view--table-body-row-drag"
               xmlns="http://www.w3.org/2000/svg"
               viewBox="0 0 24 24"
               role="img"
               aria-hidden="true"
          >
            <path :d="icons.dragVertical"></path>
          </svg>
</template>

<script lang="ts">
import {Vue, Component} from 'vue-property-decorator';
import {mdiDragVertical} from '@mdi/js';

@Component
export default class GridView extends Vue {
  readonly icons = {
    dragVertical: mdiDragVertical
  };
}
</script>

<style lang="scss" scoped>
.grid-view--table-body-row-drag {
  width: 10px;
  height: 32px;
  fill: currentColor;
}
</style>

How to add a color accent

As in deep-purple accent-4, put a space after the color name and then give the accent level:

<v-progress-linear color="deep-purple accent-4"></v-progress-linear>

How to apply custom styles that change automatically with the theme

Applying styles

You can simply bind the style attribute in the template and set the color directly. This is the worst approach.

<template>
  <div class="fill-width" :style="contentStyle"></div>
</template>

<script lang="ts">
import {Vue, Component, Prop, Watch} from 'vue-property-decorator';

@Component
export default class ViewPort extends Vue {
  get contentStyle() {
    return {'background-color': '#ffffff'};
  }
}
</script>

Using Vuetify's colors class

Just import vuetify/lib/util/colors.

<template>
  <div class="fill-width" :style="contentStyle"></div>
</template>

<script lang="ts">
import {Vue, Component, Prop, Watch} from 'vue-property-decorator';
import colors from 'vuetify/lib/util/colors'

@Component
export default class ViewPort extends Vue {
  get contentStyle() {
    if (this.$vuetify.theme.dark) {
      return {'background-color': colors.grey.darken1};
    } else {
      return {'background-color': colors.grey.lighten5};
    }
  }
}
</script>

Using Vuetify's styles.sass

A component that uses scss to apply the text.secondary color from $material-dark and $material-light as the font color, depending on the theme:

<template>
  <p class="text-subtitle-2 font-weight-bold mb-1" :class="textColorClass">
    <slot></slot>
  </p>
</template>

<script lang="ts">
import {Vue, Component, Prop} from 'vue-property-decorator';

@Component
export default class SubtitleBold extends Vue {
  @Prop({type: String})
  readonly value!: string;

  get textColorClass() {
    if (this.$vuetify.theme.dark) {
      return 'text-color-dark';
    } else {
      return 'text-color-light';
    }
  }
}
</script>

<style lang="scss" scoped>
@import '~vuetify/src/styles/styles.sass';

.text-color-light {
  color: map-get(map-get($material-light, 'text'), 'secondary');
}

.text-color-dark {
  color: map-get(map-get($material-dark, 'text'), 'secondary');
}
</style>

Using CSS selectors

The v-app documentation of Vuetify says it "propagates the application variant (dark/light) to child components"1. That v-app ends up as the following final HTML:

<div data-app="true" class="v-application v-application--is-ltr theme--dark" id="app">
   <!-- ... -->
</div>

And many Vuetify components get their background color propagated through a CSS Selector like the following:

.theme--dark.v-application {
    background: #121212;
    color: #FFFFFF;
}

Note that the theme--dark and theme--light classes switch depending on whether Vuetify's dark theme (this.$vuetify.theme.dark) is true or false.

So you can use the class selector above to specify the CSS Selector of child components.

<template>
  <div class="grid-view"></div>
</template>

<style lang="scss" scoped>
.grid-view {
}

.theme--light.v-application .grid-view {
  background: red;
}
.theme--dark.v-application .grid-view {
  background: blue;
}
</style>

This lets you specialize styles for theme changes without using javascript.

Be careful: if you use a Deep Selector like this,

.theme--light.v-application::v-deep .grid-view {
  background: red;
}

it compiles to the following.

.theme--light.v-application[data-v-eb074e2a] .grid-view {
  background: red;
}

In that case the root element cannot be found, so you must not use a Deep Selector.

For reference, without a Deep Selector it compiles to the following.

.theme--light.v-application .grid-view[data-v-eb074e2a] {
  background: red;
}

Troubleshooting

TypeScript Error: Could not find a declaration file for module 'vuetify/lib’

When applying TypeScript, you may get an error like the one below.

ERROR in C:/workspace/inhasite/general/ctlt_apply/english_clinic/src/plugins/vuetify.ts
2:21 Could not find a declaration file for module 'vuetify/lib'. 'C:/workspace/inhasite/general/ctlt_apply/english_clinic/node_modules/vuetify/lib/index.js' implicitly has an 'any' type.
  Try `npm install @types/vuetify` if it exists or add a new declaration (.d.ts) file containing `declare module 'vuetify/lib';`
    1 | import Vue from 'vue';
  > 2 | import Vuetify from 'vuetify/lib';
      |                     ^
    3 | import 'vuetify/src/stylus/app.styl';
    4 |
    5 | Vue.use(Vuetify, {
Version: typescript 3.2.2, tslint 5.11.0

Add "vuetify" to compilerOptions.types in the tsconfig.json file.

"compilerOptions": {
    "types": ["vuetify"],
}

Icon display error

First, add the dependency.

$ yarn add @mdi/font -D
// OR
$ npm install @mdi/font -D

Edit the vuetify.js file as follows.

import Vue from "vue";
import Vuetify from "vuetify/lib";
import '@mdi/font/css/materialdesignicons.css' // Ensure you are using css-loader

Vue.use(Vuetify);

export default new Vuetify({
  icons: {
    iconfont: 'mdi',
  },
});

Language change not applied to other components

See Vue I18n#Troubleshooting.

errorBuckets of v-text-field not updated on language change

See v-text-field.

Using / for division is deprecated

: Using / for division is deprecated and will be removed in Dart Sass 2.0.0.

Recommendation: math.div($grid-gutter, 3)

More info and automated migrator: https://sass-lang.com/d/slash-div

   ╷
63 │     'md': $grid-gutter / 3,
   │           ^^^^^^^^^^^^^^^^
   ╵
    node_modules/vuetify/src/styles/settings/_variables.scss 63:11  @import
    node_modules/vuetify/src/styles/settings/_index.sass 1:9        @import
    node_modules/vuetify/src/styles/styles.sass 2:9                 @import
    node_modules/vuetify/src/components/VIcon/_variables.scss 1:9   @import
    node_modules/vuetify/src/components/VIcon/VIcon.sass 2:9        root stylesheet

Quick fix devDependencies in package.json:

  • "sass": "~1.32.8"
  • "sass-loader": "10"

Translation key "dataTable.ariaLabel.****" not found in fallback

If a warning like the one above appears in the browser when using a component such as VDataTable, initialize the Vuetify plugin as follows when creating it:

import Vue from 'vue';
import Vuetify from 'vuetify/lib/framework';
import en from 'vuetify/lib/locale/en';
import ko from 'vuetify/lib/locale/ko';

Vue.use(Vuetify);

export default new Vuetify({
  lang: {
    locales: {en, ko},
    current: 'en',
  },
});

To change the language:

this.$vuetify.lang.current = this.$recc.lang;

This is separate from the language change in vue-i18n, so you have to do each one:

this.$i18n.locale = this.$recc.lang;

See also

Favorite site

Guide

Reference

author Zer0 sitemap