Categories
Vuetify

Vuetify — Menus and Drawers

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Menus

We can place menus in any component.

For example, we can write:

<template>
  <v-row>
    <v-col cols="12" sm="6" offset-sm="3">
      <v-card height="200px">
        <v-card-title class="blue white--text">
          <span class="headline">Menu</span>

          <v-spacer></v-spacer>

          <v-menu bottom left>
            <template v-slot:activator="{ on, attrs }">
              <v-btn dark icon v-bind="attrs" v-on="on">
                <v-icon>mdi-dots-vertical</v-icon>
              </v-btn>
            </template>

            <v-list>
              <v-list-item v-for="(item, i) in items" :key="i">
                <v-list-item-title>{{ item.title }}</v-list-item-title>
              </v-list-item>
            </v-list>
          </v-menu>
        </v-card-title>

        <v-card-text>Lorem Ipsum</v-card-text>
      </v-card>
    </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 put our v-menu in the v-card component.

Then v-menu has the bottom and left props so that we can place it at the bottom left of the card.

Navigation Drawers

To add a navigation drawer, we can add the v-navigation-drawer component.

For example, we can write:

<template>
  <v-row>
    <v-col cols="12">
      <v-card class="mx-auto" height="400" width="256">
        <v-navigation-drawer class="deep-purple accent-4" dark permanent>
          <v-list>
            <v-list-item v-for="item in items" :key="item.title" link>
              <v-list-item-icon>
                <v-icon>{{ item.icon }}</v-icon>
              </v-list-item-icon>

              <v-list-item-content>
                <v-list-item-title>{{ item.title }}</v-list-item-title>
              </v-list-item-content>
            </v-list-item>
          </v-list>

          <template v-slot:append>
            <div class="pa-2">
              <v-btn block>Logout</v-btn>
            </div>
          </template>
        </v-navigation-drawer>
      </v-card>
    </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 have the v-list to show a list of items.

This is put inside the v-navigation-drawer to make it show in the drawer.

Permanent Floating Drawer

We can add a navigation drawer that floats on the page.

For example, we can write:

<template>
  <v-row>
    <v-col cols="12">
      <v-card class="pa-12" color="indigo darken-2" flat>
        <v-card elevation="12" width="256">
          <v-navigation-drawer floating permanent>
            <v-list dense rounded>
              <v-list-item v-for="item in items" :key="item.title" link>
                <v-list-item-icon>
                  <v-icon>{{ item.icon }}</v-icon>
                </v-list-item-icon>

                <v-list-item-content>
                  <v-list-item-title>{{ item.title }}</v-list-item-title>
                </v-list-item-content>
              </v-list-item>
            </v-list>
          </v-navigation-drawer>
        </v-card>
      </v-card>
    </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 have the menu floating on the page with the permanent and floating props.

Conclusion

We can add the various kinds of menus with Vuetify.

Categories
Vuetify

Vuetify — Menus and Context Menu

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.

Categories
Vuetify

Vuetify — Menus

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Menus

We can add menus with the v-menu component.

For example, we can write:

<template>
  <v-row>
    <v-col cols="12">
      <div class="text-center">
        <v-menu offset-y>
          <template v-slot:activator="{ on, attrs }">
            <v-btn color="primary" dark v-bind="attrs" v-on="on">Dropdown</v-btn>
          </template>
          <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: () => ({
    items: [
      { title: "Click Me" },
      { title: "Click Me 2" },
      { title: "Click Me 3" },
    ],
  }),
};
</script>

We added a button to trigger the menu.

We pass all the attrs properties to the v-btn so that we can trigger the menu with it.

The on object has all the event listeners needed for triggering the menu.

Then we gave a v-list with the menu items.

Absolute Position

The position of the menu can be changed with the absolute prop.

For example, we can write:

<template>
  <v-row class="d-flex" justify="center">
    <v-menu v-model="showMenu" absolute offset-y style="max-width: 600px">
      <template v-slot:activator="{ on, attrs }">
        <v-card
          class="portrait"
          img="https://placekitten.com/600/600"
          height="300"
          width="600"
          v-bind="attrs"
          v-on="on"
        ></v-card>
      </template>

      <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>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      { title: "Click Me" },
      { title: "Click Me 2" },
      { title: "Click Me 3" },
    ],
  }),
};
</script>

We add the absolute prop to the v-menu so that it’ll show where the mouse is clicked.

It’ll show when we left-click on the mouse.

Menu with Activator and Tooltip

We can add a menu with a activator and a tooltip.

For example, we can write:

<template>
  <div class="text-center">
    <v-menu>
      <template v-slot:activator="{ on: menu, attrs }">
        <v-tooltip bottom>
          <template v-slot:activator="{ on: tooltip }">
            <v-btn
              color="primary"
              dark
              v-bind="attrs"
              v-on="{ ...tooltip, ...menu }"
            >Dropdown with Tooltip</v-btn>
          </template>
          <span>tooltip</span>
        </v-tooltip>
      </template>
      <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>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      { title: "Click Me" },
      { title: "Click Me 2" },
      { title: "Click Me 3" },
    ],
  }),
};
</script>

We add the tooltip with the v-tooltip wrapped around our v-btn .

We pass the event listeners from the 2 template tags to our v-btn so that we can listen to button and tooltip events.

Then we add the v-list component to add the menu items.

Conclusion

We can add a menu to our app with the v-menu component.

Categories
Vuetify

Vuetify — Nested Lists and Separators

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Nested Lists

We can add nested list with the v-list-item component.

For example, we can write:

<template>
  <v-row>
    <v-col cols="12">
      <v-card class="mx-auto" width="300">
        <v-list>
          <v-list-item>
            <v-list-item-icon>
              <v-icon>mdi-home</v-icon>
            </v-list-item-icon>

            <v-list-item-title>Home</v-list-item-title>
          </v-list-item>

          <v-list-group prepend-icon="account_circle" value="true">
            <template v-slot:activator>
              <v-list-item-title>Users</v-list-item-title>
            </template>

            <v-list-group no-action sub-group value="true">
              <template v-slot:activator>
                <v-list-item-content>
                  <v-list-item-title>Admin</v-list-item-title>
                </v-list-item-content>
              </template>

              <v-list-item v-for="(admin, i) in admins" :key="i" link>
                <v-list-item-title v-text="admin[0]"></v-list-item-title>
                <v-list-item-icon>
                  <v-icon v-text="admin[1]"></v-icon>
                </v-list-item-icon>
              </v-list-item>
            </v-list-group>

            <v-list-group sub-group no-action>
              <template v-slot:activator>
                <v-list-item-content>
                  <v-list-item-title>Actions</v-list-item-title>
                </v-list-item-content>
              </template>
              <v-list-item v-for="(crud, i) in cruds" :key="i">
                <v-list-item-title v-text="crud[0]"></v-list-item-title>
                <v-list-item-action>
                  <v-icon v-text="crud[1]"></v-icon>
                </v-list-item-action>
              </v-list-item>
            </v-list-group>
          </v-list-group>
        </v-list>
      </v-card>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    admins: [
      ["Management", "people_outline"],
      ["Settings", "settings"],
    ],
    cruds: [
      ["Create", "add"],
    ],
  }),
};
</script>

We have v-list-group inside another v-list-group .

Subheadings and Dividers

We can add headings and dividers to separate our lists.

For example, we can write:

<template>
  <v-row>
    <v-col cols="12">
      <v-card max-width="475" class="mx-auto">
        <v-toolbar color="teal" dark>
          <v-app-bar-nav-icon></v-app-bar-nav-icon>
          <v-toolbar-title>Settings</v-toolbar-title>
        </v-toolbar>

        <v-list two-line subheader>
          <v-subheader>General</v-subheader>
          <v-list-item>
            <v-list-item-content>
              <v-list-item-title>Profile photo</v-list-item-title>
              <v-list-item-subtitle>Change profile photo</v-list-item-subtitle>
            </v-list-item-content>
          </v-list-item>
        </v-list>

        <v-divider></v-divider>

        <v-list subheader two-line flat>
          <v-subheader>Hangout notifications</v-subheader>

<v-list-item-group v-model="settings" multiple>
            <v-list-item>
              <template v-slot:default="{ active }">
                <v-list-item-action>
                  <v-checkbox :input-value="active" color="primary"></v-checkbox>
                </v-list-item-action>

                <v-list-item-content>
                  <v-list-item-title>Notifications</v-list-item-title>
                  <v-list-item-subtitle>Allow notifications</v-list-item-subtitle>
                </v-list-item-content>
              </template>
            </v-list-item>
          </v-list-item-group>
        </v-list>
      </v-card>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    settings: [],
  }),
};
</script>

We have the v-subheader component to add the subheading.

And we have the v-divider to add the divider between our lists.

Conclusion

We can add subheaders and dividers to our lists.

Also, we can have nested lists in our page.

Categories
Vuetify

Vuetify — List Shapes

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Shaped Lists

We can change the shape of the list item.

For example, we can write:

<template>
  <v-row>
    <v-col cols="12">
      <v-card class="mx-auto" max-width="300" tile>
        <v-list shaped>
          <v-subheader>REPORTS</v-subheader>
          <v-list-item-group v-model="item" color="primary">
            <v-list-item v-for="(item, i) in items" :key="i">
              <v-list-item-icon>
                <v-icon v-text="item.icon"></v-icon>
              </v-list-item-icon>
              <v-list-item-content>
                <v-list-item-title v-text="item.text"></v-list-item-title>
              </v-list-item-content>
            </v-list-item>
          </v-list-item-group>
        </v-list>
      </v-card>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    item: 1,
    items: [
      { text: "Clock", icon: "mdi-clock" },
      { text: "Account", icon: "mdi-account" },
      { text: "Flag", icon: "mdi-flag" },
    ],
  }),
};
</script>

The shaped prop makes the list item displayed with rounded corners on the right side.

Dense Items

We can add the dense prop to make the items denser:

<template>
  <v-row>
    <v-col cols="12">
      <v-card class="mx-auto" max-width="300" tile>
        <v-list dense >
          <v-subheader>REPORTS</v-subheader>
          <v-list-item-group v-model="item" color="primary">
            <v-list-item v-for="(item, i) in items" :key="i">
              <v-list-item-icon>
                <v-icon v-text="item.icon"></v-icon>
              </v-list-item-icon>
              <v-list-item-content>
                <v-list-item-title v-text="item.text"></v-list-item-title>
              </v-list-item-content>
            </v-list-item>
          </v-list-item-group>
        </v-list>
      </v-card>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    item: 1,
    items: [
      { text: "Clock", icon: "mdi-clock" },
      { text: "Account", icon: "mdi-account" },
      { text: "Flag", icon: "mdi-flag" },
    ],
  }),
};
</script>

Flat

The flat prop makes the v-list items flat:

<template>
  <v-row>
    <v-col cols="12">
      <v-card class="mx-auto" max-width="300" tile>
        <v-list flat>
          <v-subheader>REPORTS</v-subheader>
          <v-list-item-group v-model="item" color="primary">
            <v-list-item v-for="(item, i) in items" :key="i">
              <v-list-item-icon>
                <v-icon v-text="item.icon"></v-icon>
              </v-list-item-icon>
              <v-list-item-content>
                <v-list-item-title v-text="item.text"></v-list-item-title>
              </v-list-item-content>
            </v-list-item>
          </v-list-item-group>
        </v-list>
      </v-card>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    item: 1,
    items: [
      { text: "Clock", icon: "mdi-clock" },
      { text: "Account", icon: "mdi-account" },
      { text: "Flag", icon: "mdi-flag" },
    ],
  }),
};
</script>

Rounded

We can make the list items have rounded corners on all sides with the rounded prop:

<template>
  <v-row>
    <v-col cols="12">
      <v-card class="mx-auto" max-width="300" tile>
        <v-list rounded>
          <v-subheader>REPORTS</v-subheader>
          <v-list-item-group v-model="item" color="primary">
            <v-list-item v-for="(item, i) in items" :key="i">
              <v-list-item-icon>
                <v-icon v-text="item.icon"></v-icon>
              </v-list-item-icon>
              <v-list-item-content>
                <v-list-item-title v-text="item.text"></v-list-item-title>
              </v-list-item-content>
            </v-list-item>
          </v-list-item-group>
        </v-list>
      </v-card>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    item: 1,
    items: [
      { text: "Clock", icon: "mdi-clock" },
      { text: "Account", icon: "mdi-account" },
      { text: "Flag", icon: "mdi-flag" },
    ],
  }),
};
</script>

Conclusion

We can add lists with various appearances with Vuetify.