Version 2 contains non backwards compatible breaking changes. This includes previously deprecated functionality from v1.x.x. These breaking changes are noted in the console for the corresponding components.
The existing grid is still operational and has an eslint plugin to help with migration. This plugin can also be used to help upgrade to the new grid.
Vuetify must now be instantiated and passed to the initial Vue instance. This is similar to how vue-router and vuex are bootstrapped.
// v1.5
// src/plugins/vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
import 'vuetify/src/stylus/app.styl'
Vue.use(Vuetify, {
iconfont: 'md',
})
// src/main.js
import Vue from 'vue'
import './plugins/vuetify'
import App from './App.vue'
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
// v2.0
// src/plugins/vuetify.js
import Vue from 'vue';
import Vuetify from 'vuetify/lib';
Vue.use(Vuetify);
export default new Vuetify({
icons: {
iconfont: 'mdi',
},
});
// src/main.js
import Vue from 'vue'
import App from './App.vue'
import vuetify from './plugins/vuetify';
Vue.config.productionTip = false
new Vue({
vuetify,
render: h => h(App)
}).$mount('#app')
// v1.5
import Vue from 'vue'
import Vuetify from 'vuetify'
import 'vuetify/src/stylus/main.styl'
const opts = { ... }
Vue.use(Vuetify, opts)
new Vue(...).$mount('#app')
// v2.0
import Vue from 'vue'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'
const opts = { ... }
Vue.use(Vuetify)
new Vue({
vuetify: new Vuetify(opts)
}).$mount('#app')
// v1.5
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
import 'vuetify/src/stylus/main.styl'
const opts = { ... }
Vue.use(Vuetify, opts)
new Vue(...).$mount('#app')
// v2.0
import Vue from 'vue'
import Vuetify from 'vuetify/lib'
const opts = { ... }
Vue.use(Vuetify)
new Vue({
vuetify: new Vuetify(opts)
}).$mount('#app')
The following components are now lazy by default. This means they will not render their content until they are explicitly activated. This drastically improves performance but may not be wanted depending upon your application's needs (i.e. For SEO purposes). To return to the previous behavior, use the eager prop.
v-badge
v-menu
v-tooltip
v-dialog
v-bottom-sheet
vuetify/lib
is now compiled to es6. This means supporting IE requires transpileDependencies
or similar to be used, along with @babel/polyfill
Now supports dark/light theme variants. The dark property has been moved into the theme property. Will dynamically change when toggling $vuetify.theme.dark. If only using one variant, you only need to define its colors.
// v1.5
const opts = {
dark: true,
theme: {
primary: '...',
...
}
}
// v2.0
const opts = {
theme: {
dark: true,
themes: {
light: {
primary: '...',
...
},
dark: {
primary: '...',
...
}
}
}
}
In order to disable the theme style sheet creation, you must use the disable property of the theme object.
// v1.5
const opts = {
theme: false
}
// v2.0
const opts = {
theme: { disable: true }
}
Icon and iconfont declaration is now scoped under the icons property.
// v1.5
const opts = {
iconfont: 'fa4',
icons: { ... }
}
// v2.0
const opts = {
icons: {
iconfont: 'fa4',
values: { ... }
}
}
- Now defaults to use mdi icons. For information on how to install please navigate here.
- Is now located under the icons property of the Vuetify options
If you want to use a custom iconfont, you must set it up in the initial Vuetify options now.
// v1.5
import Vue from 'vue'
import Vuetify from 'vuetify'
Vue.use(Vuetify, {
iconfont: 'fa4'
})
// v2.0
import Vue from 'vue'
import Vuetify from 'vuetify'
Vue.use(Vuetify, {
icons: {
iconfont: 'fa4'
}
})
Import location has changed. Must be explicitly bootstrapped with the Vuetify instance to use in vue-router scroll-behavior. Example of how to do this here. Reference documentation for scroll-behavior usage here.
// v1.5
import goTo from 'vuetify/es5/components/Vuetify/goTo'
// v2.0
import goTo from 'vuetify/lib/services/goto'
The translator function t is now nested under the lang property.
// v1.5
this.$vuetify.t(...)
// v2.0
this.$vuetify.lang.t(...)
The grid has been rebuilt modeled after bootstrap. The existing grid still works and needs some slight modifications. Kael has created an eslint plugin to help with this process.
- eslint-plugin-vuetify to fix most of these for you
- Spacing helpers have changed to represent the number of 4px intervals from 0-12 (0-48px)
- eg. px-7 is 7 * 4 = 28px
- 3 β 4
- 4 β 6
- 5 β 12
- Most "breakpointed" and "non-breakpointed" helpers have been normalised, eg.
.text-xs-center
is nowtext-center
as it applies to all screen widths unless overridden - Children of
.d-flex
no longer have extra flex rules applied. This can be done manually with.flex-grow-1
- Helper classes changed:
.fluid
β.container--fluid
.scroll-y
β.overflow-y-auto
.hide-overflow
β.overflow-hidden
.show-overflow
β.overflow-visible
.no-wrap
β.text-no-wrap
.ellipsis
β.text-truncate
.left
β.float-left
.right
β.float-right
<v-layout row>
should not be used as.row
is now part of the new grid instead (#7956)
Use the following regex to update spacing classes:
find: ([\s"][mp][axytblr])-5
replace: $1-12
find: ([\s"][mp][axytblr])-4
replace: $1-6
find: ([\s"][mp][axytblr])-3
replace: $1-4
For examples on how the v2 grid compares to v1.5, check out this github gist.
The main framework styles are now imported automatically.
// v1.5
// src/plugins/vuetify.js
import 'vuetify/src/styles/main.sass' // can be removed
Must install the sass package
yarn add sass -D
// OR
npm install sass -D
Do not install node-sass, it is not the correct library.
The root font-size (per MD2 specification) is now 16px.
- The following typography classes have been replaced:
- subheading β subtitle-1
All event names has been changed from camelCase to kebab-case:
update:searchInput
βupdate:search-input
update:inputValue
βupdate:input-value
update:miniVariant
βupdate:mini-variant
update:pickerDate
βupdate:picker-date
update:selectingYear
βupdate:selecting-year
tableDate
βupdate:table-date
update:returnValue
βupdate:return-value
- Components with activators,
v-tooltip
,v-menu
,v-dialog
,v-list-group
andv-bottom-sheet
must now be bound using the new v-slot syntax.- Requires [email protected]
- We understand this is considerably more verbose than the v1.5 counterpart. We are still exploring ways to support the new v-slot in a more concise manner.
- You can find more information on the official Vue documentation for Destructuring Slot Props.
- You can find more information on the official Vue documentation for v-slot.
- The upside to this change is it is easier to support nested activators and provide proper a11y support
<!-- v1.5 -->
<v-dialog>
<v-btn slot="activator">...</v-btn>
</v-dialog>
<!-- v2.0 -->
<v-dialog>
<template v-slot:activator="{ on }"
<v-btn v-on="on">...</v-btn>
</template>
</v-dialog>
<!-- v2.0 -->
<v-menu>
<template v-slot:activator="{ on: menu }">
<v-tooltip bottom>
<template v-slot:activator="{ on: tooltip }">
<v-btn
color="primary"
dark
v-on="{ ...tooltip, ...menu }"
>
Dropdown w/ Tooltip
</v-btn>
</template>
<span>Im A ToolTip</span>
</v-tooltip>
</template>
</v-menu>
Testing with Vuetify is now similar to that of vue-router and vuex.
// setup.js
import Vue from 'vue'
import Vuetify from 'vuetify'
Vue.use(Vuetify)
// Component.spec.js
import { createLocalVue, mount } from '@vue/test-utils'
import Vuetify from 'vuetify'
import Component from 'path/to/my/component'
const localVue = createLocalVue()
describe('Component.vue', () => {
let vuetify
beforeEach(() => {
vuetify = new Vuetify(...)
})
it('should...', () => {
const wrapper = mount(Component, {
localVue,
vuetify
})
})
})
All form inputs default to white when using the dark prop unless the application is explicitly set to dark mode.
These are previous deprecations from earlier versions that have now been removed:
<v-text-field textarea>
will no longer render<v-textarea>
<v-select autocomplete>
will no longer render<v-autocomplete>
<v-select combobox>
will no longer render<v-combobox>
<v-select overflow>
will no longer render<v-overflow-btn>
<v-select segmented>
will no longer render<v-overflow-btn segmented>
<v-select editable>
will no longer render<v-overflow-btn editable>
These are the changes required for existing components.
- Component classes have been prepended with v-. eg
.application
β.v-application
- The dark and light prop no longer have an effect on application theme variants
<!-- v1.5 src/App.vue -->
<template>
<v-app dark>
...
</v-app>
</template>
// v2.0 src/plugins/vuetify.js
import Vue from 'vue'
import Vuetify from 'vuetify'
Vue.use(Vuetify)
export default new Vuetify({
theme: { dark: true }
})
- Alerts are visible by default
<!-- v1.5 -->
<template>
<v-alert :value="true">
...
</v-alert>
</template>
<!-- v2.0 -->
<template>
<v-alert>
...
</v-alert>
</template>
- The cycle prop is no longer implicit, must be defined in order to have screens switch
- The flat prop is now text
- The round prop is now rounded
- No longer has explicit margin
- value no longer controls visibility, use active
- input event emitted when clicking
- The close event is now click:close
- @input listener is now @active.sync
<!-- v1.5 -->
<v-chip :value="chip" @input="chip = $event">...</v-chip>
<v-chip v-model="chip">...</v-chip>
<!-- v2.0 -->
<v-chip :active="chip" @update:active="chip = $event">...</v-chip>
<v-chip :active.sync="active">...</v-chip>
- Renamed from
v-bottom-nav
tov-bottom-navigation
- The color prop is now background-color
- The color prop now affects the active
<v-btn>
color
- Component has been removed
Developer notes: Was never explicitly listed in API
- The flat prop is now text
- The round prop is now rounded
- No longer has explicit margin
- Component has been removed
- The cycle prop is no longer implicit, must be defined in order to have screens switch
- The value prop is now active
- value no longer controls visibility. input event emitted when clicking
- The selected prop is now input-value or v-model
- The close event is now click:close
Data table (and iterator) have been rewritten from the ground up to be both easier to use and to allow for more flexibilty in more advanced use cases. This has resulted in a number of breaking changes. Some of these are shared between both components while some are unique to each.
- disable-initial-sort has been removed. Neither component initially sorts data anymore. Use sort-by (or options) prop to sort.
- filter prop has been removed. Instead use custom-filter. This was done in an effort to make custom filtering less confusing.
- The signature for custom-filter has changed from
(items: object[], search: string, filter: Filter): object[]
to(value: any, search: string, item: any) => boolean
- The signature for custom-filter has changed from
- pagination prop has been removed. Instead use the separate props such as page, sort-by, etc. If you want to provide a single object you can use the new options prop instead. NOTE: The options prop has a different object structure than pagination. Check API docs for details.
- total-items prop has been renamed to server-items-length
- hide-actions prop has been renamed to hide-default-footer. Also it no longer changes the visible items per page
- Props related to the default footer have been move to the footer-props prop. These are:
- prev-icon
- next-icon
- rows-per-page-items β items-per-page-options
- rows-per-page-text β items-per-page-text
- The expand prop has been removed.
- The content-tag, content-props, content-class props have been removed. Instead simply use the default scoped slot to implement your intended markup.
- items slot has been renamed to item
- headers slot renamed to header
- item slot (and header) now require you to define a
<tr>
element. Previously this was optional. - expand slot renamed to expanded-item. It no longer includes an expansion transition, and the slot is inside the
<tr>
element so that you can define your own<td>
columns. To get back to a similar look as in 1.5, you will need a<td>
with colspan equal to the number of columns in your header. - hide-header has been renamed to hide-default-header
- select-all has been renamed to show-select. This will also render a checkbox on each item row as long as you are not defining a slot that overrides the internal row rendering (such as item or body).
- Props related to the default header have been moved to the header-props prop. These are:
- sort-icon
- Many components have been renamed and props moved
v-expansion-panel
βv-expansion-panels
v-expansion-panel-content
βv-expansion-panel
- New components
v-expansion-panel-header
v-expansion-panel-content
<!-- v1.5 -->
<v-expansion-panel>
<v-expansion-panel-content
v-for="(item,i) in 5"
:key="i"
>
<template v-slot:header>Item</template>
<v-card>
...
</v-card>
</v-expansion-panel-content>
</v-expansion-panel>
<!-- v2.0 -->
<v-expansion-panels>
<v-expansion-panel
v-for="(item,i) in 5"
:key="i"
>
<v-expansion-panel-header>
Item
</v-expansion-panel-header>
<v-expansion-panel-content>
<v-card>
...
</v-card>
</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>
- Now has explicit padding to match other similar MD components. Can be removed with the padless prop or a helper class,
class="pa-0"
- Component has been removed
- Many components have been renamed
v-list-tile
βv-list-item
v-list-tile-action
βv-list-item-action
v-list-tile-avatar
βv-list-item-avatar
v-list-tile-content
βv-list-item-content
v-list-tile-title
βv-list-item-title
v-list-tile-sub-title
βv-list-item-subtitle
- The avatar prop has been removed
- Can no longer use
v-list-item
s in the activator slot- listeners are passed through to the internal
v-list-item
for activators - use
v-list-item-content
/v-list-item-title
etc instead
- listeners are passed through to the internal
- Default width has been changed from 300px to 256px. You can adjust it using width prop.
- Now passes attributes and listeners to item slot for proper a11y support (split from tile to match other implementations).
<!-- v1.5 -->
<v-select>
<template v-slot:item="{ item, tile }">
<v-list-tile v-bind="tile">
...
</v-list-tile>
</template>
</v-select>
<!-- v2.0 -->
<v-select>
<template v-slot:item="{ item, attrs, on }">
<v-list-item v-bind="attrs" v-on="on">
...
</v-list-item>
</template>
</v-select>
The item scoped slot value of { tile }
is now { attrs, on }
. is now bound similar to the v-menu
activator slot.
- No longer has a default autocomplete of on
- Icons no longer have inferred swapping for activator through css
- The activator slot will provide a model in the future
<!-- v1.5 -->
<v-speed-dial>
<template v-slot:activator>
<v-btn
dark
fab
>
<v-icon>account_circle</v-icon>
<v-icon>close</v-icon>
</v-btn>
</template>
</v-speed-dial>
<!-- v2.0 -->
<v-speed-dial v-model="fab">
<template v-slot:activator>
<v-btn
dark
fab
>
<v-icon v-if="fab">account_circle</v-icon>
<v-icon v-else>close</v-icon>
</v-btn>
</template>
</v-speed-dial>
- The color prop is now background-color. Color now affects the default text and slider color
- Various class names have been changed throughout
- v-tab__div removed, use v-tab
- v-tab__item β v-tab
- v-tabs__slider β v-tabs-slider
- v-tabs__bar β v-tabs-bar
- No longer implicitly inherits the
v-tabs
model when nested. Must have :value or v-model explicitly bound.
<!-- v1.5 -->
<v-tabs v-model="tabs">
...
<v-tabs-items>
...
</v-tabs-items>
</vtabs>
<!-- v2.0 -->
<v-tabs v-model="tabs">
...
<v-tabs-items v-model="tabs">
...
</v-tabs-items>
</vtabs>
Developer notes: The tabs-items component does not have to be provided and is only necessary for custom implementations.
- The mask prop and functionality has been removed. Instead you can use 3rd party libraries such as
vue-the-mask
.
- The box prop is now filled
<!-- v1.5 -->
<v-text-field box></v-text-field>
<!-- v2.0 -->
<v-text-field filled></v-text-field>
- The outline prop is now outlined
<!-- v1.5 -->
<v-btn outline></v-text-field>
<v-autocomplete outline></v-autocomplete>
<v-alert outline></v-alert>
<!-- v2.0 -->
<v-btn outlined></v-text-field>
<v-autocomplete outlined></v-autocomplete>
<v-alert outlined></v-alert>
- All existing scrolling techniques and
app
functionality has been deprecated and moved tov-app-bar
.
If you are stuck and need help, don't fret! We have a very large and dedicated community that is able to provide help 24/7. Come to the #release-migration channel.