Vuetify is a popular UI framework for Vue apps.
In this article, we’ll look at how to work with the Vuetify framework.
Rounded
We round the menu corners with the rounded
prop.
For example, we can write:
<template>
<v-row justify="space-around">
<v-col cols="12">
<v-menu rounded="rounded" offset-y>
<template v-slot:activator="{ attrs, on }">
<v-btn color="primary" class="white--text ma-8" v-bind="attrs" v-on="on">Menu</v-btn>
</template>
<v-list>
<v-list-item v-for="item in items" :key="item.title" link>
<v-list-item-title v-text="item.title"></v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-col>
</v-row>
</template>
<script>
export default {
name: "HelloWorld",
data: () => ({
items: [
{ title: "Click Me" },
{ title: "Click Me 2" },
{ title: "Click Me 3" },
],
}),
};
</script>
We set the rounded
prop to rounded
so that we can have a big menu.
Close on Click
Menus can be closed when focus is lost.
For example, we can write:
<template>
<v-row justify="space-around">
<v-col cols="12">
<v-menu close-on-click>
<template v-slot:activator="{ attrs, on }">
<v-btn color="primary" class="white--text ma-8" v-bind="attrs" v-on="on">Menu</v-btn>
</template>
<v-list>
<v-list-item v-for="item in items" :key="item.title" link>
<v-list-item-title v-text="item.title"></v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-col>
</v-row>
</template>
<script>
export default {
name: "HelloWorld",
data: () => ({
items: [
{ title: "Click Me" },
{ title: "Click Me 2" },
{ title: "Click Me 3" },
],
}),
};
</script>
The close-on-click
will make the menu close on click.
Absolute Position without Activator
We can place our menu with absolute position without a component to trigger it.
For example, we can write:
<template>
<v-row justify="space-around">
<v-col cols="12">
<div>
<v-row class="flex" justify="center">
<v-card
:ripple="false"
class="portrait"
img="https://placekitten.com/600/600"
height="300px"
width="300px"
@contextmenu="show"
></v-card>
</v-row>
<v-menu v-model="showMenu" :position-x="x" :position-y="y" absolute offset-y>
<v-list>
<v-list-item v-for="(item, index) in items" :key="index">
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div>
</v-col>
</v-row>
</template>
<script>
export default {
name: "HelloWorld",
data: () => ({
showMenu: false,
x: 0,
y: 0,
items: [
{ title: "Click Me" },
{ title: "Click Me 2" },
{ title: "Click Me 3" },
],
}),
methods: {
show(e) {
e.preventDefault();
this.showMenu = false;
this.x = e.clientX;
this.y = e.clientY;
this.$nextTick(() => {
this.showMenu = true;
});
},
},
};
</script>
We have the card that has the contextmenu
event listener to listen to right clicks.
When we right-click on the card, the show
method is run.
We set the showMenu
state to false
to clear the existing menu.
And set the x
and y
states are set so that we positon the menu to where the right click is done.
We set x
and y
to the position-x
and position-y
props to set the menu position.
Also, we need the absolute
prop to make the menu position in absolute position.
Conclusion
We can make the menu rounded and create a context menu with Vuetify.