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>
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>
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>
Persistent Bottom Sheets
By default, an open 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>
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>
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>
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.
Every Crazy Thing JavaScript Does
A captivating guide to the subtle caveats and lesser-known parts of JavaScript.