Categories
Vuetify

Vuetify — App Bar Behavior

Vuetify is a popular UI framework for Vue apps.

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

Collapsible Bars

The collapse and collapse-on-scroll props can easily let us control the state of the toolbar that the user interacts with.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-card class="overflow-hidden">
          <v-app-bar
            :collapse="!collapseOnScroll"
            :collapse-on-scroll="collapseOnScroll"
            absolute
            color="deep-purple accent-4"
            dark
            scroll-target="#scrolling-techniques-6"
          >
            <v-app-bar-nav-icon></v-app-bar-nav-icon>

            <v-toolbar-title>Collapsing Bar</v-toolbar-title>

            <v-spacer></v-spacer>

            <v-checkbox v-model="collapseOnScroll" color="white" hide-details></v-checkbox>
          </v-app-bar>
          <v-sheet id="scrolling-techniques-6" class="overflow-y-auto" max-height="600">
            <v-container style="height: 1000px;"></v-container>
          </v-sheet>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    collapseOnScroll: false
  }),
};
</script>

to collapse the scroll bar when collapseOnScroll is true .

collapseOnScroll is true when we click check the checkbox.

Elevate Bar on Scroll

The elevate-on-scroll prop with the v-app-bar component.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-card class="overflow-hidden">
          <v-app-bar absolute color="white" elevate-on-scroll scroll-target="#scrolling">
            <v-app-bar-nav-icon></v-app-bar-nav-icon>

            <v-toolbar-title>Title</v-toolbar-title>

            <v-spacer></v-spacer>

            <v-btn icon>
              <v-icon>mdi-magnify</v-icon>
            </v-btn>

            <v-btn icon>
              <v-icon>mdi-heart</v-icon>
            </v-btn>

            <v-btn icon>
              <v-icon>mdi-dots-vertical</v-icon>
            </v-btn>
          </v-app-bar>
          <v-sheet id="scrolling" class="overflow-y-auto" max-height="600">
            <v-container style="height: 1500px;"></v-container>
          </v-sheet>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

We just add the elevate-on-scroll to our v-app-bar to make it show a shadow when we scroll down.

Also, we have to set the scroll-target with the selector of the scroll container to make that work.

Inverted scrolling

The inverted-scroll prop lets us hide the bar until the user scrolls past the designated threshold.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-card class="overflow-hidden">
          <v-app-bar
            absolute
            color="primary"
            dark
            inverted-scroll
            scroll-target="#scrolling"
          >
            <v-app-bar-nav-icon></v-app-bar-nav-icon>

            <v-toolbar-title>Title</v-toolbar-title>

            <v-spacer></v-spacer>

            <v-btn icon>
              <v-icon>mdi-magnify</v-icon>
            </v-btn>

            <v-btn icon>
              <v-icon>mdi-heart</v-icon>
            </v-btn>

            <v-btn icon>
              <v-icon>mdi-dots-vertical</v-icon>
            </v-btn>
          </v-app-bar>
          <v-sheet id="scrolling" class="overflow-y-auto" max-height="600">
            <v-container style="height: 1500px;"></v-container>
          </v-sheet>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

We add the inverted-scroll prop to make the app bar show only when we scroll down.

Conclusion

We can change the behavior of the app bar with various props.

Categories
Vuetify

Vuetify — App Bar and Scrolling

Vuetify is a popular UI framework for Vue apps.

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

Prominent App Bar with Scroll Shrink

We can add the shrink-to-scroll prop to make the app bar shrink on scroll.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-card class="overflow-hidden">
          <v-app-bar
            absolute
            color="indigo darken-2"
            dark
            shrink-on-scroll
            prominent
            scroll-target="#scrolling"
          >
            <v-app-bar-nav-icon></v-app-bar-nav-icon>

            <v-toolbar-title>Title</v-toolbar-title>

            <v-spacer></v-spacer>

            <v-btn icon>
              <v-icon>mdi-magnify</v-icon>
            </v-btn>

            <v-btn icon>
              <v-icon>mdi-heart</v-icon>
            </v-btn>

            <v-btn icon>
              <v-icon>mdi-dots-vertical</v-icon>
            </v-btn>
          </v-app-bar>
          <v-sheet id="scrolling" class="overflow-y-auto" max-height="600">
            <v-container style="height: 1000px;"></v-container>
          </v-sheet>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

We have the v-app-bar with the v-sheet as the scroll target to watch for to determine the height of the app bar.

The app bar will shrink when we scroll the v-sheet component.

Prominent App Bar with Scroll Shrink and Image

We can add a background image to the app bar.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-card class="overflow-hidden">
          <v-app-bar
            absolute
            color="#fcb69f"
            dark
            shrink-on-scroll
            src="https://picsum.photos/1920/1080?random"
            scroll-target="#scrolling"
          >
            <template v-slot:img="{ props }">
              <v-img
                v-bind="props"
                gradient="to top right, rgba(19,84,122,.5), rgba(128,208,199,.8)"
              ></v-img>
            </template>

            <v-app-bar-nav-icon></v-app-bar-nav-icon>

            <v-toolbar-title>Title</v-toolbar-title>

            <v-spacer></v-spacer>

            <v-btn icon>
              <v-icon>mdi-magnify</v-icon>
            </v-btn>

            <v-btn icon>
              <v-icon>mdi-heart</v-icon>
            </v-btn>

            <v-btn icon>
              <v-icon>mdi-dots-vertical</v-icon>
            </v-btn>
          </v-app-bar>
          <v-sheet id="scrolling" class="overflow-y-auto" max-height="600">
            <v-container style="height: 1000px;"></v-container>
          </v-sheet>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

to add a background image with the src prop.

Also, we add a gradient with the v-img component to add a gradient background.

Hiding on Scroll

We can also hide the app bar with the hide-on-scroll prop.

For instance, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-card class="overflow-hidden">
          <v-app-bar
            absolute
            color="teal lighten-3"
            dark
            hide-on-scroll
            prominent
            scroll-target="#scrolling"
          >
            <v-app-bar-nav-icon></v-app-bar-nav-icon>

            <v-toolbar-title>Title</v-toolbar-title>

            <v-spacer></v-spacer>

            <v-btn icon>
              <v-icon>mdi-magnify</v-icon>
            </v-btn>

            <v-btn icon>
              <v-icon>mdi-heart</v-icon>
            </v-btn>

            <v-btn icon>
              <v-icon>mdi-dots-vertical</v-icon>
            </v-btn>
          </v-app-bar>
          <v-sheet id="scrolling" class="overflow-y-auto" max-height="600">
            <v-container style="height: 1000px;"></v-container>
          </v-sheet>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

We just add the hide-on-scroll prop with the scroll-target to hide the app bar when the scroll target is being scrolled.

Conclusion

We can change the app bar our way on scroll with Vuetify.

Categories
Vuetify

Vuetify — App Bar and Drawer

Vuetify is a popular UI framework for Vue apps.

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

Toggle Navigation Drawers

We can toggle the navigation drawer by using the v-app-bar-nav-icon component.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-card class="mx-auto overflow-hidden" height="400">
          <v-app-bar color="deep-purple" dark>
            <v-app-bar-nav-icon @click="drawer = true"></v-app-bar-nav-icon>

             <v-toolbar-title>Title</v-toolbar-title>
          </v-app-bar>

          <v-navigation-drawer v-model="drawer" absolute temporary>
            <v-list nav dense>
              <v-list-item-group v-model="group" active-class="deep-purple--text text--accent-4">
                <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-item>
                  <v-list-item-icon>
                    <v-icon>mdi-account</v-icon>
                  </v-list-item-icon>
                  <v-list-item-title>Account</v-list-item-title>
                </v-list-item>
              </v-list-item-group>
            </v-list>
          </v-navigation-drawer>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    drawer: false
  }),
};
</script>

We have the v-navigation-drawer to display a menu on the left side.

When it’s displayed depends on the drawer state.

If it’s true , then it’ll be displayed.

When we click on the v-app-ba-nav-icon , then we make it true .

Scroll Threshold

We can set a scroll threshold on the v-app-bar .

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-card class="overflow-hidden">
          <v-app-bar
            absolute
            color="#43a047"
            dark
            shrink-on-scroll
            prominent
            src="https://picsum.photos/1920/1080?random"
            fade-img-on-scroll
            scroll-target="#scrolling"
            scroll-threshold="500"
          >
            <template v-slot:img="{ props }">
              <v-img v-bind="props" gradient="to top right, rgba(55,236,186,.7), lightblue"></v-img>
            </template>

            <v-app-bar-nav-icon></v-app-bar-nav-icon>

            <v-toolbar-title>Title</v-toolbar-title>

            <v-spacer></v-spacer>

            <v-btn icon>
              <v-icon>mdi-magnify</v-icon>
            </v-btn>

            <v-btn icon>
              <v-icon>mdi-heart</v-icon>
            </v-btn>

            <v-btn icon>
              <v-icon>mdi-dots-vertical</v-icon>
            </v-btn>
          </v-app-bar>
          <v-sheet id="scrolling" class="overflow-y-auto" max-height="600">
            <v-container style="height: 1500px;"></v-container>
          </v-sheet>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    drawer: false,
  }),
};
</script>

We added the scroll-threshold prop to make the toolbar change from a taller toolbar with a background image to one with that has a solid background without an image.

The fade-img-on-scroll prop lets us make the image on the app bar disappear when we scroll.

Also, we’ve to set the scroll-target to the selector of the div we’re watching for scrolling.

Conclusion

We can add a navigation drawer to our app bar.

Also, we can make the app bar display differently when we scroll.

Categories
Vuetify

Vuetify — Badges and Banners

Vuetify is a popular UI framework for Vue apps.

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

Badges

The v-badge component lets us add an avatar-like icon or text onto the component to highlight information to the user.

They appear as superscripts or subscripts.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-toolbar>
          <v-tabs dark background-color="primary" grow>
            <v-tab>
              <v-badge color="pink" dot>One</v-badge>
            </v-tab>

            <v-tab>
              <v-badge color="green" content="6">Two</v-badge>
            </v-tab>

            <v-tab>
              <v-badge color="deep-purple accent-4" icon="mdi-vuetify">Three</v-badge>
            </v-tab>
          </v-tabs>
        </v-toolbar>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    alert: false,
  }),
};
</script>

We add badges to tab links with the v-tab component.

The color can be changed with the color prop.

icon lets us change the icon.

Show Badge on Hover

We can make a badge shows on hover with the v-hover component.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-badge
          :value="hover"
          color="deep-purple accent-4"
          content="1000"
          left
          transition="slide-x-transition"
        >
          <v-hover v-model="hover">
            <v-icon color="grey lighten-1" large>mdi-account-circle</v-icon>
          </v-hover>
        </v-badge>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    hover: undefined,
  }),
};
</script>

to add a badge that shows on hover.

The hover state is controlled by the hover state.

v-model son the v-hover component sets the hover state.

Dynamic Notifications

We can create dynamic notifications with badges.

The content can be controlled with the content prop.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <div>
          <v-btn class="mx-1" color="primary" @click="messages++">Send Message</v-btn>

          <v-btn class="mx-1" color="error" @click="messages = 0">Clear Notifications</v-btn>
        </div>

        <v-badge :content="messages" :value="messages" color="green" overlap>
          <v-icon large>mdi-email</v-icon>
        </v-badge>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    messages: 0,
  }),
};
</script>

We have the Send Message button that increments the message state.

This causes the content to update with the latest message value.

Banners

The v-banner component is used as a message for users with 1 to 2 actions.

It can have a single line or multiple lines.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-banner single-line :sticky="sticky">
          Hello world.
          <template v-slot:actions>
            <v-btn text color="deep-purple accent-4">Get Online</v-btn>
          </template>
        </v-banner>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    sticky: true
  }),
};
</script>

We have the v-banner component with the single-line prop to display a single line banner.

The sticky controls whether the banner is sticky or not.

Two-Line Banner

We can add a 2 line banner to store more data.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-banner>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent cursus nec sem id malesuada.
          Curabitur lacinia sem et turpis euismod, eget elementum ex pretium.
          <template
            v-slot:actions
          >
            <v-btn text color="primary">Dismiss</v-btn>
            <v-btn text color="primary">Retry</v-btn>
          </template>
        </v-banner>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

to add a longer message.

The actions slot has the action buttons.

Conclusion

We can add badges and banners to our app with Vuetify.

Categories
Vue Best Practices

Vue Best Practices— Props, Spacing, and Naming

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at some best practices for props, spacing, and naming.

Proo Name Casing

In Vue apps, props should be named in a consistent way.

They should be valid JavaScript identifier names in camelCase.

For instance, we should write:

<template>
  <div></div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String
  }
};
</script>

The prop name is msg which is a valid JavaScript identifier name.

Default Props

Having default props is a good idea.

This way, if we forget to pass in a prop, then we still have a default value set for our prop.

For instance, we can write:

<template>
  <div></div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    msg: {
      type: String,
      default: "hello"
    }
  }
};
</script>

We added a default field to our prop object.

Now if we don’t have anything passed in for the msg prop then it’s set to the 'hello' prop.

Prop Types

We can add prop types to our Vue component prop so that we won’t have props with the wrong type passed in.

For instance, we can write:

<template>
  <div></div>
</template>

<script>
export default {
  name: "HelloWorld",
  props: {
    msg: String
  }
};
</script>

Then the msg prop would always be a string.

If it’s not, we’ll get an error.

Put HTML Element Content in a New Line

If we have HTML elements content, then we can put them in a new line.

For instance, we can write:

<template>
  <tr>
    <td>{{ foo }}</td>
    <td>{{ bar }}</td>
  </tr>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      foo: 1,
      bar: 2
    };
  }
};
</script>

Then we have 2 td elements in their own line.

It’s easier to read to have them in their own line.

v-bind Directive Style

We can use : instead of v-bind to save us some typing.

For example, we can write:

<template>
  <HelloWorld :msg="msg"/>
</template>

<script>
import HelloWorld from "./components/HelloWorld";

export default {
  name: "App",
  components: {
    HelloWorld
  },
  data() {
    return {
      msg: "hi"
    };
  }
};
</script>

We have :msg which is short for v-bind .

We save typing by using the shorthand.

v-on Style

We can use @ instead of v-on . For instance, we can write:

<template>
  <button @click="onClick">click me</button>
</template>

<script>
export default {
  name: "App",
  methods: {
    onClick() {
      alert('hello')
    }
  }
};
</script>

@ is short for v-on:click .

We save typing by using the shorthand.

Use of v-html

We should be careful when we use v-html so that we don’t let attacks execute cross-site scripting attacks.

We should avoid it as much as possible and escape anything that may have code in it.

this in Template

this is Vue templates shouldn’t be used. It’s probably added as a mistake from copy and pasting in most cases.

For instance, instead of writing:

<a :href="this.url">link</a>

We should write:

<a :href="url">link</a>

Array Brackets Spacing

In our Vue apps, we should have array brackets spacing so that they’re easy to read.

For instance, we can write:

const arr = ['foo', 'bar'];

Arrow Spacing

Arrow functions should have consistent spacing.

For instance, we should write:

const fn = () => {
  //...
}

We have one space before and after the arrow.

Block Spacing

Block spacing should be consistent so that we can write:

const fn = () => {
  //...
}

We have 2 spaces for indentation.

Brace Style

We should put the opening brace on the same line as the declaration.

For instance, we should write:

if (foo) {
  baz();
} else {
  bar();
}

We have the opening brace after the closing parentheses for the if and else for the else block.

camelCase

camelCase should be used for declaring variables.

This is a commonly accepted convention so we should use it for consistency.

For instance, we write:

let fooBar = 1;

Conclusion

We should use camelCase for prop names and variables.

Spacing should be consistent throughout our code.

Default props and prop type validation are also good things to add to prevent errors.