Categories
BootstrapVue

BootstrapVue — Dropdown Customization and Embedding

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 BootstrapVue dropdowns and embed media.

Disabling Flipping

The alignment of a dropdown may change according to its viewport position.

To prevent that from happening, we can add the no-filip prop to our b-dropdown .

Menu Offset

We can add an offset to our dropdown with the offset prop.

For instance, we can write:

<template>
  <div id="app">
    <b-dropdown id="dropdown-offset" offset="25" text="Offset Dropdown" class="m-2">
      <b-dropdown-item href="#">Action</b-dropdown-item>
    </b-dropdown>
  </div>
</template>

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

Then we move the dropdown 25 pixels to the right.

Split Button

We can create a menu button that has a button that does something other than opening the dropdown in addition to opening it.

To do that, we add the split prop:

<template>
  <div id="app">
    <b-dropdown split id="dropdown" text="Dropdown" class="m-2">
      <b-dropdown-item href="#">Action</b-dropdown-item>
    </b-dropdown>
  </div>
</template>

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

Now we only have an arrow on the right that opens the dropdown.

Split Button Link

The part of a split button that doesn’t open the dropdown can open a URL.

We can add the split-href prop to open a URL.

For instance, we can write:

<template>
  <div id="app">
    <b-dropdown split id="dropdown" split-href="#foo" text="Dropdown" class="m-2">
      <b-dropdown-item href="#">Action</b-dropdown-item>
    </b-dropdown>
  </div>
</template>

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

We added split-href=”#foo” so that we’ll opening the #foo path when we click on the left part.

Split Button Type

Split button can have all the types of a button.

To specify the type, we use the split-button-type prop.

The value can be 'button' , 'submit' or 'reset' .

Sizing

We can change the size of the dropdown button with the size prop.

For instance, we can write:

<template>
  <div id="app">
    <b-dropdown id="dropdown" size="lg" text="Dropdown" class="m-2">
      <b-dropdown-item href="#">Action</b-dropdown-item>
    </b-dropdown>
  </div>
</template>

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

Then we get an extra big button.

'sm' will make the button smaller than the default size.

Dropdown Color Variants

We can set the variant prop to change the dropdown button color variant.

For instance, if we have:

<template>
  <div id="app">
    <b-dropdown id="dropdown" variant="primary" text="Dropdown" class="m-2">
      <b-dropdown-item href="#">Action</b-dropdown-item>
    </b-dropdown>
  </div>
</template>

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

Then we make it blue.

All the outline and fill variants are available.

Split Button Color Variant

If we have a split button, we can set different variants for the left and right parts.

To set the left part, we use the split-variant prop.

To set the right part, we use the variant prop.

For instance, we can write:

<template>
  <div id="app">
    <b-dropdown
      id="dropdown"
      split
      split-variant="outline-primary"
      variant="primary"
      text="Dropdown"
      class="m-2"
    >
      <b-dropdown-item href="#">Action</b-dropdown-item>
    </b-dropdown>
  </div>
</template>

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

Now the left part has a blue outline and text.

And the right part has a blue background and a white arrow tip.

Block Level Dropdowns

Dropdowns can be block level.

This means it fills the whole page width.

To make the dropdown a block element, we add the block prop

For instance, we can write:

<template>
  <div id="app">
    <b-dropdown id="dropdown" block text="Dropdown" class="m-2">
      <b-dropdown-item href="#">Action</b-dropdown-item>
    </b-dropdown>
  </div>
</template>

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

Now the button fills the viewport since we added the block prop to b-dropdown .

block can be combined with the split button props to make a block-level split button.

Embedding Items Responsively

BootstrapVue comes with a b-embed component to embed things responsively.

To use it, we can write:

<template>
  <div id="app">
    <b-embed
      type="iframe"
      aspect="16by9"
      src="https://www.youtube.com/embed/wtH-hdOF1uA?rel=0"
      allowfullscreen
    ></b-embed>
  </div>
</template>

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

We just set the src prop to the YouTube video’s embed URL to embed a YouTube video.

allowfullscreen means that we allow the video to go full screen.

aspect is the aspect ratio, which we set to 16 by 9.

type is the type of object we want to embed. YouTube videos embedded in an iframe, so we set it to 'iframe' .

In addition to iframes, we can also embed video, embed and object elements.

We can also add source elements inside b-embed components to embed what we want.

Conclusion

We can customize our dropdowns with various options.

b-embed can be used to embed items.

Categories
BootstrapVue

BootstrapVue — Accordions and Dropdowns

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 an accordion and a dropdown with BootstrapVue.

Accordions

We can create an accordion with the b-collapse component.

To create one, we’ve to nest it inside a b-card component.

For instance, we can write:

<template>
  <div id="app">
    <b-card no-body class="mb-1">
      <b-card-header header-tag="header" class="p-1" role="tab">
        <b-button block href="#" v-b-toggle.accordion-1 variant="info">accordion 1</b-button>
      </b-card-header>
      <b-collapse id="accordion-1" visible accordion="my-accordion" role="tabpanel">
        <b-card-body>
          <b-card-text>accordion 1 text</b-card-text>
        </b-card-body>
      </b-collapse>
    </b-card>

    <b-card no-body class="mb-1">
      <b-card-header header-tag="header" class="p-1" role="tab">
        <b-button block href="#" v-b-toggle.accordion-2 variant="info">accordion 2</b-button>
      </b-card-header>
      <b-collapse id="accordion-2" accordion="my-accordion" role="tabpanel">
        <b-card-body>
          <b-card-text>accordion 2 text</b-card-text>
        </b-card-body>
      </b-collapse>
    </b-card>

    <b-card no-body class="mb-1">
      <b-card-header header-tag="header" class="p-1" role="tab">
        <b-button block href="#" v-b-toggle.accordion-3 variant="info">accordion 3</b-button>
      </b-card-header>
      <b-collapse id="accordion-3" accordion="my-accordion" role="tabpanel">
        <b-card-body>
          <b-card-text>accordion 3 text</b-card-text>
        </b-card-body>
      </b-collapse>
    </b-card>
  </div>
</template>

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

We have 3 cards which are combined to create our accordion.

We have the b-card components on the outside.

Then we have the b-collapse component on the inside to create the accordion.

This way, we have the headers always displayed.

But the body is only displayed when we clicked on the heading, which also hides the other cards.

Dropdowns

Dropdowns are toggleable and contextual overlays for displaying list of links and actions.

To create one, we create the b-dropdown component with some b-dropdown-item components inside.

For instance, we can create a simple dropdown by writing:

<template>
  <div id="app">
    <b-dropdown id="dropdown-1" text="menu" class="m-md-2">
      <b-dropdown-item>apple</b-dropdown-item>
      <b-dropdown-divider></b-dropdown-divider>
      <b-dropdown-item active>active</b-dropdown-item>
      <b-dropdown-item disabled>disabled</b-dropdown-item>
    </b-dropdown>
  </div>
</template>

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

We have the b-dropdown component with the text prop, which is set to the text of the drop-down button.

Therefore, we set our dropdown button text to 'menu' since that’s the value we have for text .

Inside it, we have the b-dropdown-item with various props.

The content is between the tags.

active makes a dropdown item active.

disabled makes a dropdown item disabled.

b-dropdown-divider is a divider on our dropdown menu.

Dropdown Button Content

We can customize our content of a drop with a template element to fill the button-content slot.

For instance, we can write:

<template>
  <div id="app">
    <b-dropdown>
      <template v-slot:button-content>
        <b>menu</b>
      </template>
      <b-dropdown-item>apple</b-dropdown-item>
    </b-dropdown>
  </div>
</template>

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

We have the template element which fills the button-content as indicated by v-slot:button-content .

Inside it, we have <b>menu</b> to show bold text.

Below it, we have the usual dropdown items.

Menu Alignment

The menu alignment can change according to our preference.

The default is to left-align the menu.

If we want to right-align the menu, we can add the right prop to the b-dropdown component.

For instance, we can write:

<template>
  <div id="app" style="padding: 100px">
    <b-dropdown right text="right">
      <b-dropdown-item>apple</b-dropdown-item>
    </b-dropdown>
  </div>
</template>

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

to right-align the menu if there’s enough room on the left edge of the screen.

Otherwise, it’ll go back to left aligning the menu.

Dropup

We can also make the menu stay above the button instead of below it.

We just have to add the dropup prop.

For example, we write:

<template>
  <div id="app" style="padding-top: 100px">
    <b-dropdown dropup text="right">
      <b-dropdown-item>apple</b-dropdown-item>
    </b-dropdown>
  </div>
</template>

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

to do that.

Drop Right or Left

We can add similar props to make the menu show on the right or left instead of above or below the button.

dropright makes it show to the right of the button.

dropleft makes it show on the left of the button.

Conclusion

We can create accordion with cards and the collapse components.

Also, BootstrapVue has menu components we can use.

Categories
BootstrapVue

BootstrapVue — Carousel and Collapse

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 a carousel and collapse components into a Vue app.

Carousel

A carousel is a slide show for cycling through a series of content.

It can include image, text, or custom markup.

BootstrapVue’s carousel has support for previous/next controls and indicators.

We can add one by using the b-carousel component.

To use it, we can write:

<template>
  <div id="app">
    <b-carousel
      v-model="slide"
      :interval="5000"
      controls
      indicators
      background="#ababab"
      img-width="1024"
      img-height="480"
      @sliding-start="onSlideStart"
      @sliding-end="onSlideEnd"
    >
      <b-carousel-slide caption="cat" text="cat" img-src="https://placekitten.com/g/600/200"></b-carousel-slide>

<b-carousel-slide img-src="https://picsum.photos/1024/480/?image=54">
        <h1>hello</h1>
      </b-carousel-slide>
    </b-carousel>

<p class="mt-4">
      Slide #: {{ slide }}
      <br>
      Sliding: {{ sliding }}
    </p>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      slide: 0,
      sliding: null
    };
  },
  methods: {
    onSlideStart(slide) {
      this.sliding = true;
    },
    onSlideEnd(slide) {
      this.sliding = false;
    }
  }
};
</script>

We have a carousel in the component above.

interval indicates that we cycle through the code every 5 seconds.

slide is the index of the slide we’re on.

controls indicates that we show the controls

indicators indicates that we show the dashes to show which slide we’re on.

background is the background color if it’s shown.

img-width is the slide image width in pixels.

img-height is the slide image height in pixels.

sliding-start is the handler that runs when the slide starts sliding.

sliding-end is the handler that runs when the slide finishes sliding.

The handlers have the slide parameter to get the slide index.

v-model is set to slide to set the slide state with the value being the slide index.

Crossfade Animation

We can add crossfade animation with the fade prop on the b-carousel component.

Disabling Animation

To disable animation, we can use the no-animation prop on the b-carousel component.

Slide Wrapping

The no-wrap prop added to b-carousel will disable the carousel wrapping back to the first slide.

Collapse

The collapse component is a box with content that can be toggled on and off.

To use it we use the v-b-toggle directive with the b-collapse component.

For instance, we can write:

<template>
  <div id="app">
    <b-button v-b-toggle.collapse-1 variant="primary">toggle</b-button>
    <b-collapse id="collapse-1" class="mt-2">
      <b-card>
        <p class="card-text">collapse content</p>
      </b-card>
    </b-collapse>
  </div>
</template>

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

We have a b-button that has the v-b-toggle directive and with the collapse-1 modifier to indicate that it’s toggling the b-collapse component with the ID collapse-1 on and off.

Then we can see the b-collapse component being toggled.

We can nest collapse component inside another component by adding b-collapse and a component with the v-b-toggle .

For instance, we can write:

<template>
  <div id="app">
    <b-button v-b-toggle.collapse-1 variant="primary">toggle</b-button>
    <b-collapse id="collapse-1" class="mt-2">
      <b-card>
        <p class="card-text">collapse content</p>
        <b-button v-b-toggle.collapse-1-inner size="sm">toggle inner</b-button>
        <b-collapse id="collapse-1-inner" class="mt-2">
          <b-card>inner content</b-card>
        </b-collapse>
      </b-card>
    </b-collapse>
  </div>
</template>

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

We have:

<b-button v-b-toggle.collapse-1-inner size="sm">toggle inner</b-button>
<b-collapse id="collapse-1-inner" class="mt-2">
  <b-card>inner content</b-card>
</b-collapse>

which is the inner collapse component.

We can toggle it on and off the same way.

We just have to make sure that we don’t use the same IDs as the outer one.

v-model

We can get the collapsed state of the collapse component by binding a state with v-model .

For instance, we can write:

<template>
  <div id="app">
    <b-button v-b-toggle.collapse-1 variant="primary">toggle</b-button>
    <b-collapse id="collapse-1" class="mt-2" v-model="visible">
      <b-card>
        <p class="card-text">collapse content</p>
      </b-card>
    </b-collapse>
    <p>{{visible}}</p>
  </div>
</template>

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

We added v-model to bind to the visible state so we can set the visibility state as the value of that property.

Then visible will show true if the collapse is expanded and false otherwise.

Conclusion

We can create a carousel with BoostrapVue. The slide options and controls can be changed.

Collapse is a component that we can toggle on and off.

Categories
BootstrapVue

BootstrapVue — Cards

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 cards to our Vue app.

Cards

In Bootstrap, cards are a flexible and extensible content container.

It can gold header, footer, and content.

The background colors can also be changed.

To add a card, we can use the b-card component.

For instance, we can write:

<template>
  <div id="app">
    <b-card
      title="Card Title"
      img-src="https://placekitten.com/g/600/200"
      img-alt="cat"
      img-top
      tag="article"
      style="max-width: 20rem;"
      class="mb-2"
    >
      <b-card-text>a cat</b-card-text>

<b-button href="#" variant="primary">Go</b-button>
    </b-card>
  </div>
</template>

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

We have the b-card component with a few props.

The img-src is the URL for an image.

img-alt is the alt attribute for the image.

style has the styles for the card.

class has the class for the card.

b-card-text has the content for the card.

title has the title for the card.

img-top indicates that the card image is at the top of the card.

We also have a button with the link.

We can also place thre image at the bottom with image-bottom .

To add a reader, we can use the header prop.

Likewise, we can add the footer prop for the footer.

We can add a header and footer by writing the following:

<template>
  <div id="app">
    <b-card
      header="header"
      header-tag="header"
      footer="footer"
      footer-tag="footer"
      title="title"
    >
      <b-card-text>Header and footers</b-card-text>
      <b-button href="#" variant="primary">Go</b-button>
    </b-card>
  </div>
</template>

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

We just add the props the place we expect them to be added in the b-card component to add headers and footers.

Horizontal Layout

We don’t have to stick with a vertical layout.

We can also create a card with a horizontal layout with b-row and b-col for layout.

For instance, we can write:

<template>
  <div id="app">
    <b-card no-body class="overflow-hidden">
      <b-row no-gutters>
        <b-col md="6">
          <b-card-img src="https://placekitten.com/200/50" alt="cat"></b-card-img>
        </b-col>
        <b-col md="6">
          <b-card-body title="Horizontal Card">
            <b-card-text>card</b-card-text>
          </b-card-body>
        </b-col>
      </b-row>
    </b-card>
  </div>
</template>

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

We have b-col to divide up the card into 2 halves.

md with value 6 means that we have a left column and a right column.

no-body means that we don’t let BootstrapVue add the card body automatically.

Instead, we used b-card-body to place the body of the card.

b-row makes sure that the b-col components stay in the row.

Text Variants

We can change the text string with the bg-variant prop.

For instance, we can write:

<template>
  <div id="app">
    <b-card bg-variant="dark" text-variant="white" title="title">
      <b-card-text>more content</b-card-text>
      <b-button href="#" variant="primary">Go</b-button>
    </b-card>
  </div>
</template>

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

We set bg-variant to 'dark' to make the background dark gray.

title is still the card title.

text-variant is the styling for the card text, which we change to white.

Other variants include primary, secondary, success, info, warning, danger, light, and dark.

Bordered

We can add borders to our cards.

To do that, we use the border-variant prop.

For instance, we can write:

<template>
  <div id="app">
    <b-card border-variant="warning" header="header" header-border-variant="warning" align="center">
      <b-card-text>lorem ipsum.</b-card-text>
    </b-card>
  </div>
</template>

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

We have the header prop to set the header text.

header-border-variant to set the border style of the header.

border-variant is used to set the border style of the body.

Header and Footer variants

Headers and footers have their own variants.

We can set them with the header-bg-variant and footer-bg-variant respectively.

Those will set the background color.

There’s also the header-border-variant and footer-border-variant props to set the border styles of the header and footer.

Nav Integration

We can add navbar integration into a card by using the b-nav component.

To add a navbar to a card, we can write:

<template>
  <div id="app">
  <b-card title="Ctitle" body-class="text-center" header-tag="nav">
    <template v-slot:header>
      <b-nav card-header tabs>
        <b-nav-item active>active</b-nav-item>
        <b-nav-item>inactive</b-nav-item>
        <b-nav-item disabled>disabled</b-nav-item>
      </b-nav>
    </template>

    <b-card-text>
      lorem ipsum.
    </b-card-text>

<b-button variant="primary">go</b-button>
  </b-card>
  </div>
</template>

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

We just put the b-nav component in the template tag to add the navbar.

It’s put into the header slot as indicated by the v-slot:header directive.

We have the active prop to set a link to be active.

If there’s no active prop set then it’s inactive.

If there’s a disabled prop, then it’s disabled.

Conclusion

There are many things that we can do with cards.

We can style it, change the layout, and add a navbar to it.

Categories
BootstrapVue

Introduction to Bootstrap Vue

BootstrapVue is the Vue version of Bootstrap. Like the plain JavaScript version of Bootstrap, it has many kinds of elements to let us style our page and make them look good.

BoostrapVue has the same elements, but they’re all available as Vue components. Therefore, we can add them straight into our Vue app without much hassle.

In this article, we’ll look at how use BootstrapVue in our Vue app to make it look good.

Getting Started

Getting started with BootstrapVue is easy. We need Vue 2.6 in our app but Vue 2.6.11 is recommended. At least Bootstrap 4.3.1 is required. Also, PortalVue 2.1 is required by Toasts.

To install it, we run:

npm install vue bootstrap-vue bootstrap

Then we register the BootstrapVue library in our app so we can use the components and directives in our app’s components.

Assuming that we used the Vue CLI to generate our Vue project, we add the following code register the BootstrapVue libraries in our app:

main.js:

import Vue from "vue";
import App from "./App.vue";
import { BootstrapVue, IconsPlugin } from "bootstrap-vue";
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

Vue.use(BootstrapVue);
Vue.use(IconsPlugin);

Vue.config.productionTip = false;

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

In the code above, we imported the CSS and the called Vue.use to register BootstrapVue for the core library and IconsPlugin for the icons.

To register individual components and directives manually, we can write the following in the entry point file of our Vue app:

Vue.component('b-modal', BModal)
Vue.directive('b-modal', VBModal)

The individual components of the BootstrapVue library can also be imported individually into our app. For instance, if we only want to include the Bootstrap modal in our app, we write:

import { ModalPlugin } from 'bootstrap-vue'
Vue.use(ModalPlugin)

in the same file.

We can also import the component straight into our component if we want to use them in our component. For instance, we can write:

import { BModal, VBModal } from 'bootstrap-vue'

Vue.component('modal-component', {
  components: {
    'b-modal': BModal
  },
  directives: {
    'b-modal': VBModal
  }
})

to import the modal from BootstrapVue and then register them in our component so that we can use them.

Basic Form Controls

One of the common components in a web app are probably forms and the corresponding inputs. BootstrapVue has form controls that are commonly used like text inputs, checkboxes, files inputs, radio buttons, dropdowns, etc.

To make a simple form with BootstrapVue, we can write the following:

App.vue:

<template>
  <div id="app">
    <b-form @submit.prevent="onSubmit" @reset="onReset">
      <b-form-group label="Name:" description="Enter your name" id="name">
        <b-form-input
          id="name-group"
          v-model="form.name"
          type="text"
          required
          placeholder="Enter name"
        ></b-form-input>
      </b-form-group>

      <b-form-group id="email-group" label="Email:" label-for="email">
        <b-form-input id="email" v-model="form.email" required placeholder="Enter email"></b-form-input>
      </b-form-group>

      <b-form-group id="fruit-group" label="Fruit:" label-for="favorite-fruit">
        <b-form-select id="favorite-fruit" v-model="form.fruit" :options="fruits" required></b-form-select>
      </b-form-group>

      <b-form-group id="sign-up">
        <b-form-checkbox-group v-model="form.choices" id="sign-up">
          <b-form-checkbox value="foo">I want foo</b-form-checkbox>
          <b-form-checkbox value="bar">I want bar</b-form-checkbox>
        </b-form-checkbox-group>
      </b-form-group>

      <b-button type="submit" variant="primary">Submit</b-button>
      <b-button type="reset" variant="danger">Reset</b-button>
    </b-form>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      fruits: ["apple", "orange", "banana"],
      form: {}
    };
  },
  methods: {
    onSubmit(){
      console.log(this.form)
    },
    onReset(){
      alert('Form reset')
    }
  }
};
</script>

In the code above, we wrap our controls in the b-form-group component, which corresponds to the form group in the plain JavaScript version of Bootstrap. Inside each b-form-group, we have our form control. If it’s a text input, then we use the b-form-input component. It takes the v-model directive to bind the input value to the model.

The b-form-select component is a dropdown. It takes the options prop, which binds to an array of values and display them in the dropdown as the choices. v-model binds to the selected choice.

The b-form-checkbox component renders the checkbox control. They reside inside the b-form-checkbox-group component, which takes the v-model directive that binds to an array of the checked choices.

b-buttons are render buttons. We can set the style with the variant prop. It also takes the type prop, which sets the type attribute of the button.

All of them items above are wrapped inside the b-form component. It handles the submit event and reset event just like a regular HTML form. In the code above, we have the @submit.prevent directive to prevent the default submit action, so it’ll run onSubmit and log the value.

The onReset handler runs when we click Reset to reset the form.

Inline form

We can add the inline prop on b-form to display form controls and buttons on a single horizontal row.

For instance, we can make a form with an inline input, checkbox and button as follows:

<template>
  <div id="app">
    <b-form inline>
      <label class="sr-only" for="name">Name</label>
      <b-input-group class="mb-2 mr-sm-2 mb-sm-0">
        <b-input id="name" placeholder="Name" v-model='form.name'></b-input>
      </b-input-group>

      <b-form-checkbox class="mb-2 mr-sm-2 mb-sm-0">Remember me</b-form-checkbox>

      <b-button variant="primary">Save</b-button>
    </b-form>
  </div>
</template>

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

All we did was add inline to the b-form as an attribute. Then everything inside is inline.

Form Validation Feedback

The b-form-invalid-feedback component lets us add feedback when an invalid inputs are entered into an input. There’s also a b-form-valid-feedback to indicate that a valid value is inputted into the input box.

For instance, we can use it as follows:

<template>
  <div>
    <b-form @submit.stop.prevent>
      <label for="email">Email</label>
      <b-input v-model="form.email" :state="validation" id="email-user"></b-input>
      <b-form-invalid-feedback :state="validation">Email not valid.</b-form-invalid-feedback>
      <b-form-valid-feedback :state="validation">Email is valid.</b-form-valid-feedback>
    </b-form>
  </div>
</template>

<script>
export default {
  name: "App",
  computed: {
    validation(){
      return /^\S+@\S+$/.test(this.form.email)
    }
  },
  data() {
    return {
      form: {}
    };
  }
};
</script>

In the code above, we have an input which takes an email. We use a computed property to compute the validity of the inputted text to see if it’s actually an email address. This computation is done in the validation function.

The resulting validation computed property is set as the value of the state prop. Then if validation returns true we display the b-form-valid-feedback component. Otherwise, we display the b-form-invalid-feedback component.

The b-input component also takes the state prop with the value set to validation. The border and icon on the right changes depending if the input is valid. If validation returns true, which means the inputted value is valid, then the border turns green and a check mark icon is displayed. Otherwise, the border turns red and an exclamation mark icon is displayed.

If we don’t want to display any validation feedback and we have the state prop added onto the components, we can set the value to null.

Radio Button

We can use the b-form-group with the b-form-radio-group nested inside to create a group of radio buttons. b-form-radio-group takes the options prop which is the options for the radio button group. It also takes the v-model directive to bind the radio value that’s selected to the model.

For example, we can add the radio button as follows:

<template>
  <div>
    <b-form-group label="Favorite Fruit">
      <b-form-radio-group
        id="radio-group"
        v-model="selected"
        :options="options"
        name="radio"
      ></b-form-radio-group>
    </b-form-group>
    <p>{{selected}}</p>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      selected: "apple",
      options: [
        { text: "apple", value: "apple" },
        { text: "orange", value: "orange" },
        { text: "banana", value: "third", disabled: true },
        { text: "grape", value: { name: 'grape' } }
      ]
    };
  }
};
</script>

In the code above, we have an options array with the data for the choices. The text property will be displayed to the user as the text for each choice. The value will be the selected value. It doesn’t matter what kind of object or value it is. As we can see, anything works.

When we click the value, we get the value selected set as the value of selected.

Images

Bootstrap has the b-img component for displaying images. It’s useful because it makes images responsive so they won’t be larger than their parent elements.

We can use it as follows:

<template>
  <div>
    <b-img
      src="https://images.unsplash.com/reserve/bOvf94dPRxWu0u3QsPjF_tree.jpg?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=755&q=80"
      fluid
      alt="tree"
    ></b-img>
  </div>
</template>

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

The code above creates a responsive image automatically. It also takes an alt attribute like a regular img element for accessibility.

We can also change fluid to fluid-grow so that the image fills the screen’s width if it’s smaller than width of the screen.

It also has a feature to round the corner of images. To make an image with rounded corners, we can add the rounded prop to the b-img component. If we don’t pass in any value, then all corners are rounded.

We can also set the values as follows:

  • true or no value: round all corners
  • false or prop not present: no rounding or corners (default)
  • 'top': round the top corners
  • 'right': round the right corners
  • 'bottom': round the bottom corners
  • 'left': round the left corners
  • 'circle': make a circle (if square image) or oval (if not square) border
  • '0': turn off rounding of corners

We can make an oval image as follows:

<template>
  <div>
    <b-img
      src="https://images.unsplash.com/reserve/bOvf94dPRxWu0u3QsPjF_tree.jpg?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=755&q=80"
      fluid
      rounded='circle'
      alt="tree"
    ></b-img>
  </div>
</template>

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

Tables

Tables are an important part of many apps. Therefore, like the regular version of Bootstrap, BootstrapVue also has a table component built in.

We can create a table by using the b-table component. Then we don’t have to create a table from scratch. For instance, we can create a table with some data and an explicit mapping of table fields to the headings by writing:

<template>
  <div>
    <b-table striped hover :items="items" :fields='fields'></b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      fields: [
        { key: "firstName", label: "First" },
        { key: "lastName", label: "Last" },
        "age",
      ],
      items: [
        { age: 38, firstName: "Jane", lastName: "Smith" },
        { age: 21, firstName: "Alex", lastName: "May" },
        { age: 16, firstName: "Mary", lastName: "Jones" },
      ]
    };
  }
};
</script>

In the code above, we have the fields object, which has the key, which is the property names of the items entries. The label is the heading text of the column of the corresponding field name. So firstName in the item from the items entry corresponds has the First heading. The lastName in the item from the items entry has the Last heading.

Modals

Modals are also an important part of many apps. We need them to overlay the page for dialog boxes and other similar things.

BootstrapVue has the b-modal component to make creating modal dialogs easy. We just need to set the id prop of the b-modal and then we use the id name as the v-b-modal‘s directive modifier on the element that’ll open when the element is clicked so that the element will open the modal with the id that we set.

The title is set so that we can set the title of the modal.

For instance, we can write the following to show the modal when a button is clicked:

<template>
  <div>
    <b-button v-b-modal.modal-simple>Show modal</b-button>

    <b-modal id="modal-simple" title="Simple Modal">
      <p>Hello!</p>
    </b-modal>
  </div>
</template>

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

In the code above, we have the v-b-modal.modal-simple directive on the button to show the modal with the id. Then the modal will show ‘Simple Modal’ as the title once it’s opened.

The modal also has the OK and Cancel button by default.

Conclusion

With BootstrapVue, we can create a Vue app that has styled components fast. It has components for form controls, tables, images, and many more that aren’t shown in this article. It’s easy to use and so we can get results fast.

To components also lets us write cleaner code. As we can see from the b-table example, we didn’t have to reference the table elements at all to create a table. We just need the data and the b-table component will map the fields to table cells.