Categories
Vuetify

Vuetify — Images

Vuetify is a popular UI framework for Vue apps.

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

Images

We can add images with the v-img component.

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-img src="https://picsum.photos/510/300?random" aspect-ratio="1.7"></v-img>
        <v-img src="https://picsum.photos/510/300?random" aspect-ratio="2"></v-img>
        <v-img src="https://picsum.photos/510/300?random" aspect-ratio="1.4"></v-img>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
  methods: {
    next() {
      alert("You clicked next");
    },
  },
};
</script>

to add images with the v-img component.

src has the URL of the image.

aspect-ratio has the aspect ratio of the image.

Height

We can change the height with the height and max-height props.

For example, we can write:

<template>
  <v-container class="fill-height" fluid style="min-height: 434px">
    <v-fade-transition mode="out-in">
      <v-row key="0">
        <v-col cols="6">
          <v-card>
            <v-img src="https://picsum.photos/350/165?random" height="125" class="grey darken-4"></v-img>
            <v-card-title class="title">height</v-card-title>
          </v-card>
        </v-col>

        <v-col cols="6">
          <v-card>
            <v-img
              src="https://picsum.photos/350/165?random"
              height="125"
              contain
              class="grey darken-4"
            ></v-img>
            <v-card-title class="title">height with contain</v-card-title>
          </v-card>
        </v-col>

        <v-col cols="6">
          <v-card>
            <v-img
              src="https://picsum.photos/350/165?random"
              max-height="125"
              class="grey darken-4"
            ></v-img>
            <v-card-title class="title">max-height</v-card-title>
          </v-card>
        </v-col>

        <v-col cols="6">
          <v-card>
            <v-img
              src="https://picsum.photos/350/165?random"
              max-height="125"
              contain
              class="grey darken-4"
            ></v-img>
            <v-card-title class="title">max-height with contain</v-card-title>
          </v-card>
        </v-col>
      </v-row>
    </v-fade-transition>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

contain prevents the image from being cropped if it doesn’t fit.

Fixed Ratio

We can set the aspect ratio if we want to change the aspect ratio of the image.

For example, we can write:

<template>
  <v-container fluid>
    <v-slider v-model="width" min="200" max="500" step="1"></v-slider>
    <v-navigation-drawer :width="width" :value="true" stateless>
      <v-img :aspect-ratio="16/9" src="https://cdn.vuetifyjs.com/images/parallax/material.jpg"></v-img>

      <v-list>
        <template v-for="(item, i) in items">
          <v-divider v-if="item.divider" :key="i"></v-divider>
          <v-list-item v-else :key="item.title">
            <v-list-item-action>
              <v-icon>{{ item.icon }}</v-icon>
            </v-list-item-action>
            <v-list-item-title>{{ item.title }}</v-list-item-title>
          </v-list-item>
        </template>
      </v-list>
    </v-navigation-drawer>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    width: 300,
    items: [
      { icon: "inbox", title: "Inbox" },
      { icon: "star", title: "Starred" },
    ],
  }),
};
</script>

We have width prop to change the width.

And we render the icons with the v-list component.

The aspect-ratio prop makes the aspect ratio of the image fixed.

Placeholder

We can add a placeholder slot to add a placeholder content inside.

For example, we can write:

<template>
  <v-container fluid>
    <v-row align="center" justify="center">
      <v-img
        src="https://bad.src/not/valid"
        lazy-src="https://picsum.photos/id/11/100/60"
        aspect-ratio="1"
        class="grey lighten-2"
        max-width="500"
        max-height="300"
      >
        <template v-slot:placeholder>
          <v-row class="fill-height ma-0" align="center" justify="center">
            <v-progress-circular indeterminate color="grey lighten-5"></v-progress-circular>
          </v-row>
        </template>
      </v-img>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

We have an src prop that is invalid, so the placeholder image will be shown.

lazy-src has the URL of the placeholder.

And we use the placeholder slot to put a circular progress display over the placeholder image.

Conclusion

We can display images with placeholders and more.

Categories
Vuetify

Vuetify — Image Gradients and Lists

Vuetify is a popular UI framework for Vue apps.

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

Gradients

We add the gradient prop can be used to apply a gradient overlay to the image.

For example, we can write:

<template>
  <v-container fluid>
    <v-row>
      <v-col cols="6" sm="4">
        <v-img
          src="https://cdn.vuetifyjs.com/images/parallax/material2.jpg"
          gradient="to top right, rgba(100,115,201,.33), rgba(25,32,72,.7)"
        ></v-img>
      </v-col>

      <v-col cols="6" sm="4">
        <v-img src="https://cdn.vuetifyjs.com/images/parallax/material2.jpg">
          <div class="fill-height bottom-gradient"></div>
        </v-img>
      </v-col>

      <v-col cols="6" sm="4">
        <v-img src="https://cdn.vuetifyjs.com/images/parallax/material2.jpg">
          <div class="fill-height repeating-gradient"></div>
        </v-img>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

to add an image with a div below it with the gradient.

Grid

We can put v-img components in a grid.

For example, we can write:

<template>
  <v-row>
    <v-col cols="12" sm="6" offset-sm="3">
      <v-card>
        <v-container fluid>
          <v-row>
            <v-col v-for="n in 9" :key="n" class="d-flex child-flex" cols="4">
              <v-card flat tile class="d-flex">
                <v-img
                  :src="`https://picsum.photos/500/300?image=${n * 5 + 10}`"
                  :lazy-src="`https://picsum.photos/10/6?image=${n * 5 + 10}`"
                  aspect-ratio="1"
                  class="grey lighten-2"
                >
                  <template v-slot:placeholder>
                    <v-row class="fill-height ma-0" align="center" justify="center">
                      <v-progress-circular indeterminate color="grey lighten-5"></v-progress-circular>
                    </v-row>
                  </template>
                </v-img>
              </v-card>
            </v-col>
          </v-row>
        </v-container>
      </v-card>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

We create v-row and v-col to contain the images.

v-img is in the v-card so that it’s placed properly.

The placeholder slot has the circular progress display to show when the image loads.

Lists

We can use the v-list component to add lists to our app.

For example, we can write:

<template>
  <v-row>
    <v-col cols="12">
      <v-card class="mx-auto" max-width="300" tile>
        <v-list disabled>
          <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: "Real-Time", icon: "mdi-clock" },
      { text: "Audience", icon: "mdi-account" },
      { text: "Conversions", icon: "mdi-flag" },
    ],
  }),
};
</script>

We have a list with the v-list component.

v-list-item display the items.

v-list-item-icon places the icon to the left of the text.

v-list-item-content adds the content.

v-list-item-title has the title text.

Conclusion

We can add gradients to images and lists with Vuetify.

Categories
Vuetify

Vuetify — Icons

Vuetify is a popular UI framework for Vue apps.

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

Material Design Icons

Vuetify comes with many icons.

We can install Material Design icons by running:

npm install material-design-icons-iconfont -D

Then in src/plugins/vuetify.js , we add:

import 'material-design-icons-iconfont/dist/material-design-icons.css'

And then we can add them with the v-icon component:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-container fluid>
          <v-row justify="space-around" class="mb-2">
            <span class="group pa-2">
              <v-icon>home</v-icon>
              <v-icon>event</v-icon>
              <v-icon>info</v-icon>
            </span>
          </v-row>
        </v-container>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

Font Awesome Icons

We can install Font Awesome icons by running:

npm install @fortawesome/fontawesome-free -D

Then in src/plugins/vuetify.js , we add:

import '@fortawesome/fontawesome-free/css/all.css'

so we can use the icons.

Then we can use it by writing:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-row align="center" justify="space-around">
          <v-icon>fas fa-lock</v-icon>
          <v-icon>fas fa-search</v-icon>
          <v-icon>fas fa-list</v-icon>
          <v-icon>fas fa-edit</v-icon>
          <v-icon>fas fa-tachometer-alt</v-icon>
          <v-icon>fas fa-circle-notch fa-spin</v-icon>
        </v-row>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

Button Icons

We can add icons to buttons.

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <div>
          <v-btn class="ma-2" color="primary" dark>
            Accept
            <v-icon dark right>mdi-checkbox-marked-circle</v-icon>
          </v-btn>

          <v-btn class="ma-2" color="red" dark>
            Decline
            <v-icon dark right>mdi-cancel</v-icon>
          </v-btn>

          <v-btn class="ma-2" dark>
            <v-icon dark left>mdi-minus_circle</v-icon>Cancel
          </v-btn>
        </div>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

to add an icon beside the icon text.

Clickable

We can bind to any click event with v-icon .

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-card>
          <v-toolbar color="pink" dark dense flat>
            <v-toolbar-title class="body-2">Upcoming Changes</v-toolbar-title>
          </v-toolbar>
          <v-card-text>Lorem ipsum.</v-card-text>

          <v-card-actions>
            <v-spacer></v-spacer>
            <v-icon large @click="next">mdi-chevron-right</v-icon>
          </v-card-actions>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
  methods: {
    next() {
      alert("You clicked next");
    },
  },
};
</script>

We set the @click directive to next so that the next method will be called when we click on the icon.

Conclusion

We can add Material Design and Font Awesome icons to our app.

Also, Vuetify comes with built-in icons.

Categories
Vuetify

Vuetify — Hover

Vuetify is a popular UI framework for Vue apps.

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

Hover

The v-hover component lets us handle hover states for any component.

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-hover v-slot:default="{ hover }">
          <v-card :elevation="hover ? 12 : 2" class="mx-auto" height="350" max-width="350">
            <v-card-text class="my-4 text-center title">Hover over me!</v-card-text>
          </v-card>
        </v-hover>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

to add the hover functionality with the v-hover component.

We can add the disabled prop to v-hover to disable hover effects.

Open/Close Delay

We can set a delay when opening or closing the hover effect with the open-delay and close-delay props.

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-hover v-slot:default="{ hover }" open-delay="200">
          <v-card :elevation="hover ? 12 : 2" class="mx-auto" height="350" max-width="350">
            <v-card-text class="my-4 text-center title">Hover over me!</v-card-text>
          </v-card>
        </v-hover>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

to set a 200ms open delay.

Hover List

We can make a hover list with the v-hover component.

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-container class="pa-4 text-center">
          <v-row class="fill-height" align="center" justify="center">
            <template v-for="(item, i) in items">
              <v-col :key="i" cols="12" md="4">
                <v-hover v-slot:default="{ hover }">
                  <v-card :elevation="hover ? 12 : 2" :class="{ 'on-hover': hover }">
                    <v-img :src="item.img" height="225px">
                      <v-card-title class="title white--text">
                        <v-row class="fill-height flex-column" justify="space-between">
                          <p class="mt-4 subheading text-left">{{ item.title }}</p>

<div>
                            <p
                              class="ma-0 body-1 font-weight-bold font-italic text-left"
                            >{{ item.text }}</p>
                            <p
                              class="caption font-weight-medium font-italic text-left"
                            >{{ item.subtext }}</p>
                          </div>
                        </v-row>
                      </v-card-title>
                    </v-img>
                  </v-card>
                </v-hover>
              </v-col>
            </template>
          </v-row>
        </v-container>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        title: "Title",
        text: "Text",
        subtext: "Subtext",
        img: "https://picsum.photos/200",
      },
      {
        title: "Title",
        text: "Text",
        subtext: "Subtext",
        img: "https://picsum.photos/200",
      },
      {
        title: "Title",
        text: "Text",
        subtext: "Subtext",
        img: "https://picsum.photos/200",
      },
    ],
    transparent: "rgba(255, 255, 255, 0)",
  }),
};
</script>

We have 3 slides each in their own v-card component.

They are inside a v-hover component so that we see a hover effect when our mouse is over the square.

Transitions

We can add our own transitions for v-hover .

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-hover v-slot:default="{ hover }">
          <v-card class="mx-auto" color="grey lighten-4" max-width="600">
            <v-img :aspect-ratio="16/9" src="[https://cdn.vuetifyjs.com/images/cards/kitchen.png](https://cdn.vuetifyjs.com/images/cards/kitchen.png)">
              <v-expand-transition>
                <div
                  v-if="hover"
                  class="d-flex transition-fast-in-fast-out orange darken-2 v-card--reveal display-3 white--text"
                  style="height: 100%;"
                >$100.99</div>
              </v-expand-transition>
            </v-img>
            <v-card-text class="pt-6" style="position: relative;">
              <v-btn absolute color="orange" class="white--text" fab large right top>
                <v-icon>mdi-cart</v-icon>
              </v-btn>
              <div class="font-weight-light grey--text title mb-2">Perfect meal</div>
            </v-card-text>
          </v-card>
        </v-hover>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

<style>
.v-card--reveal {
  align-items: center;
  bottom: 0;
  justify-content: center;
  opacity: 0.5;
  position: absolute;
  width: 100%;
}
</style>

to add a v-expand-transition to create our hover effect.

We display the price when we hover over the image.

The styles make the overlay text centered and translucent.

Conclusion

We can add hover effect with the v-hover component.

The transition is built-in but we can also customize to what we want.

Categories
Vuetify

Vuetify — Slide Group

Vuetify is a popular UI framework for Vue apps.

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

Slide Item Active Class

We can change the active class of the slide items with the active-class prop:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-sheet class="mx-auto" elevation="8" max-width="800">
          <v-slide-group
            v-model="model"
            class="pa-4"
            prev-icon="mdi-minus"
            next-icon="mdi-plus"
            show-arrows
            active-class="success"
          >
            <v-slide-item v-for="n in 15" :key="n" v-slot:default="{ active, toggle }">
              <v-card
                :color="active ? 'primary' : 'grey lighten-1'"
                class="ma-4"
                height="200"
                width="100"
                [@click](http://twitter.com/click "Twitter profile for @click")="toggle"
              >
                <v-row class="fill-height" align="center" justify="center">
                  <v-scale-transition>
                    <v-icon
                      v-if="active"
                      color="white"
                      size="48"
                      v-text="'mdi-close-circle-outline'"
                    ></v-icon>
                  </v-scale-transition>
                </v-row>
              </v-card>
            </v-slide-item>
          </v-slide-group>
        </v-sheet>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    model: undefined,
  }),
};
</script>

The show-arrows prop make the navigation arrow show on both sies.

Also, we have the active-class prop to style the selected item differently.

Mandatory

We can make at least one item be selected in the group with the mandatory prop:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-sheet class="mx-auto" elevation="8" max-width="800">
          <v-slide-group
            v-model="model"
            class="pa-4"
            prev-icon="mdi-minus"
            next-icon="mdi-plus"
            show-arrows
            mandatory
          >
            <v-slide-item v-for="n in 15" :key="n" v-slot:default="{ active, toggle }">
              <v-card
                :color="active ? 'primary' : 'grey lighten-1'"
                class="ma-4"
                height="200"
                width="100"
                @click="toggle"
              >
                <v-row class="fill-height" align="center" justify="center">
                  <v-scale-transition>
                    <v-icon
                      v-if="active"
                      color="white"
                      size="48"
                      v-text="'mdi-close-circle-outline'"
                    ></v-icon>
                  </v-scale-transition>
                </v-row>
              </v-card>
            </v-slide-item>
          </v-slide-group>
        </v-sheet>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    model: undefined,
  }),
};
</script>

Now the first item will be selected by default.

Pseudo Carousel

We can display content below the selected slide.

For example, we can write:

<template>
  <v-container class="grey lighten-5">
    <v-row>
      <v-col>
        <v-sheet class="mx-auto" elevation="8" max-width="800">
          <v-slide-group v-model="model" class="pa-4" show-arrows>
            <v-slide-item v-for="n in 15" :key="n" v-slot:default="{ active, toggle }">
              <v-card
                :color="active ? 'primary' : 'grey lighten-1'"
                class="ma-4"
                height="200"
                width="100"
                @click="toggle"
              >
                <v-row class="fill-height" align="center" justify="center">
                  <v-scale-transition>
                    <v-icon
                      v-if="active"
                      color="white"
                      size="48"
                      v-text="'mdi-close-circle-outline'"
                    ></v-icon>
                  </v-scale-transition>
                </v-row>
              </v-card>
            </v-slide-item>
          </v-slide-group>

          <v-expand-transition>
            <v-sheet v-if="model != null" color="grey lighten-4" height="200" tile>
              <v-row class="fill-height" align="center" justify="center">
                <h3 class="title">{{ model }}</h3>
              </v-row>
            </v-sheet>
          </v-expand-transition>
        </v-sheet>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    model: undefined,
  }),
};
</script>

We added the v-expand-transition component below the v-slide-group to show what we want to the user.

We’ll see a transition effect when we click on the item.

model has the index of the item we clicked on.

Conclusion

We can add slides with the v-slide-group component and let us select items when we click on it.