Categories
BootstrapVue

BootstrapVue — More Complex Navigation

To make good looking Vue apps, we need to style our components.

To make our lives easier, we can use components with styles built-in.

In this article, we’ll look at how to add navigation components.

Inline Forms

The b-nav-form lets us add forms into the navbar.

For example, we can write:

<template>
  <div id="app">
    <b-nav>
      <b-nav-item active>foo</b-nav-item>
      <b-nav-item>bar</b-nav-item>
      <b-nav-form @submit.stop.prevent="submit">
        <b-form-input></b-form-input>
        <b-button type="submit">Ok</b-button>
      </b-nav-form>
    </b-nav>
  </div>
</template>
<script>
export default {
  name: "App",
  methods: {
    submit(){
      alert('success')
    }
  }
};
</script>

We have the b-form-input inside the b-nav-form .

We can call a submit handler by setting the submit event handler on the b-nav-form .

Card Integration

We can add a navbar inside a card.

For instance, we can write:

<template>
  <div id="app">
    <b-card title="Card Title" no-body>
      <b-card-header header-tag="nav">
        <b-nav card-header tabs>
          <b-nav-item active>foo</b-nav-item>
          <b-nav-item>bar</b-nav-item>
          <b-nav-item disabled>baz</b-nav-item>
        </b-nav>
      </b-card-header>

      <b-card-body class="text-center">
        <b-card-text>Content.</b-card-text>

        <b-button variant="primary">Do Something</b-button>
      </b-card-body>
    </b-card>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

We just put the b-nav inside the b-card-header .

Then we add the card-header prop to make it fit inside the card header.

tabs makes it show up as tabs.

Alternatively, we can change it to the pills style:

<template>
  <div id="app">
    <b-card title="Card Title" no-body>
      <b-card-header header-tag="nav">
        <b-nav card-header pills>
          <b-nav-item active>foo</b-nav-item>
          <b-nav-item>bar</b-nav-item>
          <b-nav-item disabled>baz</b-nav-item>
        </b-nav>
      </b-card-header>

      <b-card-body class="text-center">
        <b-card-text>Content.</b-card-text>

        <b-button variant="primary">Do Something</b-button>
      </b-card-body>
    </b-card>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

We can also remove the card-header prop if we want a plain style navbar:

<template>
  <div id="app">
    <b-card title="Card Title" no-body>
      <b-card-header header-tag="nav">
        <b-nav>
          <b-nav-item active>foo</b-nav-item>
          <b-nav-item>bar</b-nav-item>
          <b-nav-item disabled>baz</b-nav-item>
        </b-nav>
      </b-card-header>

      <b-card-body class="text-center">
        <b-card-text>Content.</b-card-text>

        <b-button variant="primary">Do Something</b-button>
      </b-card-body>
    </b-card>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

Use with Vue Router

We can use nav with Vue Router. To do this, we have to define a parent route and a set of child routes.

For example, we can write:

main.js

import Vue from "vue";
import App from "./App.vue";
import { BootstrapVue } from "bootstrap-vue";
import "bootstrap/dist/css/bootstrap.css";
import "bootstrap-vue/dist/bootstrap-vue.css";
import VueRouter from "vue-router";
import Foo from "./components/Foo";
import Bar from "./components/Bar";
import Root from "./components/Root";

const routes = [
  {
    path: "/",
    component: Root,
    children: [
      {
        path: "foo",
        component: Foo
      },
      {
        path: "bar",
        component: Bar
      }
    ]
  }
];

const router = new VueRouter({
  routes
});

Vue.use(VueRouter);
Vue.use(BootstrapVue);
Vue.config.productionTip = false;

new Vue({
  router,
  render: h => h(App)
}).$mount("#app");

We added the VueRouter plugin and the routes.

We have to have a parent route for the nav and child routes for displaying the content in the route.

The child routes are in the children prop.

Then we add:

App.vue

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

This is the parent router-view .

Then we add our nav and child router-view :

components/Root.vue

<template>
  <div id="app">
    <b-card title="Card Title" no-body>
      <b-card-header header-tag="nav">
        <b-nav>
          <b-nav-item to="/foo" exact exact-active-class="active">foo</b-nav-item>
          <b-nav-item to="/bar" exact exact-active-class="active">bar</b-nav-item>
        </b-nav>
      </b-card-header>

      <b-card-body class="text-center">
        <router-view></router-view>
      </b-card-body>
    </b-card>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

We have b-nav-item with the to prop. And we have the exact prop to match the route exactly.

exact-active-class is a CSS class that’s applied when the route is navigated to.

Then we add our child routes:

component/Foo.vue :

<template>
  <p>foo</p>
</template>

<script>
export default {};
</script>

component/Bar.vue :

<template>
  <p>bar</p>
</template>

<script>
export default {};
</script>

Conclusion

We can add various things to our nav like inline forms.

Also, we can put the nav in cards.

It also integrates with Vue Router so we can navigate to routes with navs.

Categories
BootstrapVue

BootstrapVue — Layouts and Lists

To make good looking Vue apps, we need to style our components. To make our lives easier, we can use components with styles built-in. In this article, we’ll look at how to add layouts.

Offsetting Columns

We can add offsets to columns to spread them out.

For example, we can write:

<template>  
  <div id="app">  
    <b-container>  
      <b-row>  
        <b-col md="4">foo</b-col>  
        <b-col md="4" offset-md="4">bar</b-col>  
      </b-row>  
    </b-container>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

We have offset-md='4' to space them out at the md breakpoint by 4 columns.

We can change the offsets at different breakpoints.

For instance, we can write:

<template>  
  <div id="app">  
    <b-container>  
      <b-row>  
        <b-col md="4">foo</b-col>  
        <b-col md="4" offset-md="4" col-lg="6" offset-lg="0">bar</b-col>  
      </b-row>  
    </b-container>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

We set the column to 6 for the lg breakpoint to set the column width to 6 for wide screens.

offset-lg is 0 to remove column spaces for wide screens.

Margins

We can add classes like mr-auto or ml-auto to add margins to our columns.

For example, we can write:

<template>  
  <div id="app">  
    <b-container>  
      <b-row>  
        <b-col md="4">foo</b-col>  
        <b-col md="4" class="ml-md-auto">bar</b-col>  
      </b-row>  
    </b-container>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

Then we add some margins to our right column.

Nesting Grids

We can nest grids.

For instance, we can write:

<template>  
  <div id="app">  
    <b-container>  
      <b-row>  
        <b-col md="4">  
          <b-row>  
            <b-col cols="8" sm="6">foo</b-col>  
            <b-col cols="4" sm="6">bar</b-col>  
          </b-row>  
        </b-col>  
      </b-row>  
    </b-container>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

We just put a b-row inside a b-col to nest it.

Row Columns

We can set the cols prop on b-row to specify the number of columns that can be in a row.

For instance, we can write:

<template>  
  <div id="app">  
    <b-container>  
      <b-row cols="2">  
        <b-col>foo</b-col>  
        <b-col>bar</b-col>  
        <b-col>baz</b-col>  
      </b-row>  
    </b-container>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

We have 3 columns but col is set to 2.

So the last b-col is below the rest.

We can also have a different number of columns at different breakpoints.

For instance, we can write:

<template>  
  <div id="app">  
    <b-container>  
      <b-row cols="1" cols-sm="2" cols-md="4" cols-lg="6">  
        <b-col>foo</b-col>  
        <b-col>bar</b-col>  
        <b-col>baz</b-col>  
        <b-col>a</b-col>  
        <b-col>b</b-col>  
      </b-row>  
    </b-container>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

We display 1, 2, 4, or 6 columns depending on the breakpoint.

Links

BootstrapVue has the b-link component to let us add links.

For example, we can write:

<template>  
  <div id="app">  
    <b-link href="http://example.com">example</b-link>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

We have the b-link component and the href prop to set the link URL.

The content is displayed in between the tags.

Disabled Link

The disabled prop disables the link.

For example, we can write:

<template>  
  <div id="app">  
    <b-link href="http://example.com" disabled>example</b-link>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

Now we have a link that does nothing when we click it.

List Group

The b-list-group component lets us create a list.

For example, we can write:

<template>  
  <div id="app">  
    <b-list-group>  
      <b-list-group-item>foo</b-list-group-item>  
      <b-list-group-item>bar</b-list-group-item>  
    </b-list-group>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

Then we display a box with a list that has the texts.

Photo by Keyur Nandaniya on Unsplash

Active List Group Items

We can add the active prop to set an item as the active item.

We can write:

<template>  
  <div id="app">  
    <b-list-group>  
      <b-list-group-item active>foo</b-list-group-item>  
      <b-list-group-item>bar</b-list-group-item>  
    </b-list-group>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

to make the first item active.

Conclusion

We can add a list group. Columns can be spaced out or we can specify the number of columns in a row.

Categories
BootstrapVue

BootstrapVue — Input Group Customizations and Jumbotrons

To make good looking Vue apps, we need to style our components.

To make our lives easier, we can use components with styles built-in.

In this article, we’ll look at how to customize input groups and creating jumbotrons.

Radio Button Addon

We can add a radio button to the input group’s left or right side with BootstrapVue’s b-form-radio component.

For example, we can write:

<template>
  <div id="app">
    <b-input-group>
      <b-input-group-prepend is-text>
        <b-form-radio></b-form-radio>
      </b-input-group-prepend>
      <b-form-input></b-form-input>
    </b-input-group>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

Switches

We can add a switch to the left or right of the input group with the b-form-checkbox component.

For example, we can write:

<template>
  <div id="app">
    <b-input-group>
      <b-input-group-prepend is-text>
        <b-form-checkbox switch></b-form-checkbox>
      </b-input-group-prepend>
      <b-form-input></b-form-input>
    </b-input-group>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

The switch prop makes the checkbox a switch style checkbox.

Multiple Inputs

We can have multiple inputs in our input groups.

For example, we can write:

<template>
  <div id="app">
    <b-input-group prepend="names">
      <b-form-input placeholder="first name"></b-form-input>
      <b-form-input placeholder="last name"></b-form-input>
    </b-input-group>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

We have 2 input boxes side by side along with the ‘names’ text prepended to the 2 input boxes.

Multiple Addons

We can have multiple addons side by side.

All we have to do is to place them where we want to.

For example, we can write:

<template>
  <div id="app">
    <b-input-group>
      <b-input-group-prepend is-text>
        <input type="checkbox">
      </b-input-group-prepend>
      <b-input-group-prepend is-text>
        <b>$</b>
      </b-input-group-prepend>
      <b-form-input placeholder="name"></b-form-input>
    </b-input-group>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

We have 2 b-oinput-group-prepend components besides each other.

Dropdown Addons

We can add drop downs as add-ons to an input group.

We just have to put them in the prepend and append slots.

For instance, we can write:

<template>
  <div id="app">
    <b-input-group>
      <template v-slot:prepend>
        <b-dropdown text="fruit" variant="info">
          <b-dropdown-item>apple</b-dropdown-item>
          <b-dropdown-item>orange</b-dropdown-item>
        </b-dropdown>
      </template>

      <b-form-input placeholder="name"></b-form-input>
    </b-input-group>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

We have the template tag that populates the prepend slot as indicated by the v-slot:prepend directive.

We placed our b-dropdown inside it.

Now we’ll see the dropdown on the left of the input box.

Likewise, we can change prepend to append if we want to place our dropdown to the right of our input box.

Control Sizing

We can change the sizing of the form group with the size prop.

For example, we can write:

<template>
  <div id="app">
    <b-input-group size="sm" prepend="label">
      <b-form-input placeholder="name"></b-form-input>
    </b-input-group>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

The whole form group is shrunk because the size prop is set to 'sm' .

We can also set it to 'lg' to make it bigger.

Sizing Custom Radio, Checkbox and Switch Addons

The size prop is added to the b-input-group to change the size of everything in the form group.

Validation States

Input groups don’t support validation state displays.

But the input inside it does support this feature.

Jumbotron

A jumbotron is a component that can extend the entire viewport to showcase marketing messages on our site.

We can set the heading and lead text using the header and lead props.

Also, we can use the header and lead named slots if we need to show HTML.

For example, we can write:

<template>
  <div id="app">
    <b-jumbotron header="Hello" lead="Lead">
      <p>World</p>
      <b-button variant="primary" href="#">Go Somewhere</b-button>
    </b-jumbotron>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

We have the b-jumbotron component with the header prop set to 'Hello' .

It’s displayed at the top and it’s the largest.

lead is set to 'Lead' and it’s displayed below the header text.

The content inside the tags is displayed inside the box.

Conclusion

We can add items to the input groups we addons.

Also, we can add a jumbotron component to display text that will catch people’s attention.

Categories
BootstrapVue

BootstrapVue — Drop-Down Customization

To make good looking Vue apps, we need to style our components.

To make our lives easier, we can use components with styles built-in.

In this article, we’ll look at how to customize dropdowns.

Mixing Options

We can mix various kinds of options together.

For example, we can write:

<template>
  <div id="app">
    <b-form-select v-model="selected" :options="options">
      <template v-slot:first>
        <b-form-select-option :value="null" disabled>choose one</b-form-select-option>
      </template>

<b-form-select-option value="apple">Apple</b-form-select-option>
      <b-form-select-option value="orange">Orange</b-form-select-option>
    </b-form-select>
    <p>{{ selected }}</p>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      selected: null
    };
  }
};
</script>

v-slot:first means that it’ll end up in the first slot, which means it’ll be displayed above the rest.

We also have other options below it.

Options Properties

We can change the options by adding various properties.

The text property is displayed to the user.

Alternative, we can render HTML with the html prop.

However, if we choose to display HTML, then we’ve to be careful about cross-site scripting attacks since what’s displayed won’t be sanitized.

HTML isn’t rendered by all browsers.

The value property is set as the state.

disabled disables the option.

For instance, we can write:

<template>
  <div id="app">
    <b-form-select v-model="selected" :options="options"></b-form-select>
    <p>{{ selected }}</p>
  </div>
</template>
<script>
export default {
  name: "App",
  data() {
    return {
      selected: null,
      options: [
        { value: null, text: "Select a Fruit" },
        { value: "apple", html: "<b>Apple</b>" },
        { value: "orange", text: "Orange" },
        { value: "grape", text: "Grape", disabled: true }
      ]
    };
  }
};
</script>

The value prop can be anything including objects.

The field names can be changed with the value-field and text-field props.

value-field lets us change the value field to something other than value ,

text-field lets us change the text field to something other than text .

For example, we can write:

<template>
  <div id="app">
    <b-form-select v-model="selected" value-field="item" text-field="name" :options="options"></b-form-select>
    <p>{{ selected }}</p>
  </div>
</template>
<script>
export default {
  name: "App",
  data() {
    return {
      selected: null,
      options: [
        { item: null, name: "Select a Fruit" },
        { item: "orange", name: "Orange" },
        { item: "grape", name: "Grape" }
      ]
    };
  }
};
</script>

We set text-field to 'name' and value-field to 'item' so we can use the fields in the options like the display text and the value respectively.

Select Sizing

We can use the select-size prop to set the size of the select list box.

For instance, we can write:

<template>
  <div id="app">
    <b-form-select v-model="selected" :select-size="5" :options="options"></b-form-select>
    <p>{{ selected }}</p>
  </div>
</template>
<script>
export default {
  name: "App",
  data() {
    return {
      selected: null,
      options: [
        { value: null, text: "Select a Fruit" },
        { value: "orange", text: "Orange" },
        { value: "grape", text: "Grape" }
      ]
    };
  }
};
</script>

Then we see a box that we can select items from instead of a dropdown.

Multiple Select

The multiple prop lets us add a select box where we can select multiple items.

For example, we can write:

<template>
  <div id="app">
    <b-form-select v-model="selected" multiple :select-size="5" :options="options"></b-form-select>
    <p>{{ selected }}</p>
  </div>
</template>
<script>
export default {
  name: "App",
  data() {
    return {
      selected: null,
      options: [
        { value: null, text: "Select a Fruit" },
        { value: "orange", text: "Orange" },
        { value: "grape", text: "Grape" },
        { value: "apple", text: "Apple" }
      ]
    };
  }
};
</script>

The selected state’s value will be an array instead of a string.

We need to use multiple with the select-size prop to display the box.

Sizing

The size prop on the b-form-select component can control its size.

'sm' sets is to extra small.

'lg' sets it to be bigger than the default.

Autofocus

The autofocus prop lets us set the focus of the dropdown select.

Value Validation

Like other input controls, we can set the state prop to display the validation status of the dropdown.

For example, we can write:

<template>
  <div id="app">
    <b-form-select v-model="selected" :state="isValid" :options="options"></b-form-select>
    <p>{{ selected }}</p>
  </div>
</template>
<script>
export default {
  name: "App",
  data() {
    return {
      selected: null,
      options: [
        { value: null, text: "Select a Fruit" },
        { value: "orange", text: "Orange" },
        { value: "grape", text: "Grape" },
        { value: "apple", text: "Apple" }
      ]
    };
  },
  computed: {
    isValid() {
      return !!(this.selected && this.selected.length > 0);
    }
  }
};
</script>

We have the isValid computed property to check the this.selected state for the choice.

And we set that to the value of the state prop.

Then we’ll see everything green when a choice is picked and red otherwise.

Conclusion

There are many things we can do with dropdowns.

We can add a validation state display.

Also, we can change the size and the field options.

We can also allow users to pick multiple items at once.

Categories
BootstrapVue

BootstrapVue — Navigation

To make good looking Vue apps, we need to style our components.

To make our lives easier, we can use components with styles built-in.

In this article, we’ll look at how to add navigation components.

Navs

BootstrapVue comes with a b-nav component to let us add a navigation bar to our app.

For example, we can write:

<template>
  <div id="app">
    <b-nav>
      <b-nav-item active>foo</b-nav-item>
      <b-nav-item>bar</b-nav-item>
      <b-nav-item disabled>baz</b-nav-item>
    </b-nav>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

We have the b-nav component, which has b-nav-item components inside.

The active prop makes a nav item active.

disabled makes it grayed out and not clickable.

Tab Style

We can add the tabs prop to make the navbar look like tabs.

For instance, we can write:

<template>
  <div id="app">
    <b-nav tabs>
      <b-nav-item active>foo</b-nav-item>
      <b-nav-item>bar</b-nav-item>
      <b-nav-item disabled>baz</b-nav-item>
    </b-nav>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

Now the active tab has lines surrounding it.

The rest is the same.

Pill Style

The pills prop makes the nav items look like buttons.

For example, we can write:

<template>
  <div id="app">
    <b-nav pills>
      <b-nav-item active>foo</b-nav-item>
      <b-nav-item>bar</b-nav-item>
      <b-nav-item disabled>baz</b-nav-item>
    </b-nav>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

Small Size

We can make the nav items smaller than the default with the small prop:

<template>
  <div id="app">
    <b-nav small>
      <b-nav-item active>foo</b-nav-item>
      <b-nav-item>bar</b-nav-item>
      <b-nav-item disabled>baz</b-nav-item>
    </b-nav>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

Fill

The fill prop makes the nav extends to its full width:

<template>
  <div id="app">
    <b-nav fill>
      <b-nav-item active>foo</b-nav-item>
      <b-nav-item>bar</b-nav-item>
      <b-nav-item disabled>baz</b-nav-item>
    </b-nav>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

Justified

The justified prop lets us make nav items equal width and the nav occur al horizontal space:

<template>
  <div id="app">
    <b-nav justified>
      <b-nav-item active>foo</b-nav-item>
      <b-nav-item>bar</b-nav-item>
      <b-nav-item disabled>baz</b-nav-item>
    </b-nav>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

Alignment

We can add the align prop to align the nav items the way we like.

The value can be left , center , or right .

For example, we can write:

<template>
  <div id="app">
    <b-nav align="right">
      <b-nav-item active>foo</b-nav-item>
      <b-nav-item>bar</b-nav-item>
      <b-nav-item disabled>baz</b-nav-item>
    </b-nav>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

Since we set align to 'right' , we have the nav items on the right.

Vertical Variation

The navbar can be made vertical with the vertical prop:

<template>
  <div id="app">
    <b-nav vertical>
      <b-nav-item active>foo</b-nav-item>
      <b-nav-item>bar</b-nav-item>
      <b-nav-item disabled>baz</b-nav-item>
    </b-nav>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

Dropdowns

We can add dropdowns into the navbar.

To do that, we use the b-nav-item-dropdown component:

<template>
  <div id="app">
    <b-nav>
      <b-nav-item active>foo</b-nav-item>
      <b-nav-item>bar</b-nav-item>
      <b-nav-item-dropdown text="fruit" toggle-class="nav-link-custom" right>
        <b-dropdown-item>apple</b-dropdown-item>
        <b-dropdown-divider></b-dropdown-divider>
        <b-dropdown-item>banana</b-dropdown-item>
      </b-nav-item-dropdown>
    </b-nav>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

We just put the b-nav-item-dropdown component into the b-nav and we get a dropdown displayed.

Text Content

We can add text content to a navbar with the b-nav-text component:

<template>
  <div id="app">
    <b-nav>
      <b-nav-item active>foo</b-nav-item>
      <b-nav-item>bar</b-nav-item>
      <b-nav-text>text</b-nav-text>
    </b-nav>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

Conclusion

We can add navbars to an app with the b-nav component.

The b-nav-item is an item that’s shown inside the navbar.

We can also add dropdown and forms inside the navbar.