How to Use Bootstrap in a Vue Project demo repo

Bootstrap (opens new window) is an open source toolkit for developing with HTML, CSS, and JS.

BootstrapVue (opens new window) is an implementation of the Bootstrap v4.5 component and grid system available for Vue.js v2.6, complete with extensive and automated WAI-ARIA accessibility markup.

WARNING

BootstrapVue is not compatible with Vue 3 at the time of this writing, so it will only be used for Vue 2.

# 👣 Steps

  1. Create a Vue project and install Bootstrap and BootstrapVue for v2. Install Bootstrap, jQuery, and Popper.js instead for v3.
    npm i -g @vue/cli
    vue create vue2-demo
    cd vue2-demo
    npm i bootstrap bootstrap-vue
    
    npm i -g @vue/cli
    vue create vue-demo
    cd vue-demo
    npm i bootstrap jquery popper.js
    
    // Make sure to add code blocks to your code group
    1. Register Bootstrap in src/main.js.
      import { BootstrapVue } from "bootstrap-vue";
      Vue.use(BootstrapVue);
      
      import "jquery/dist/jquery.slim.min.js";
      import "popper.js/dist/popper.min.js";
      import "bootstrap/dist/js/bootstrap.min.js";
      
      // Make sure to add code blocks to your code group
      1. Customize Bootstrap, e.g. in src/assets/custom-bootstrap.scss. The path to the default variables is bootstrap/scss/_variables.scss.
      $primary: #359499;
      $secondary: #98ddde;
      $success: #81894e;
      $info: #185190;
      $warning: #ffdb3b;
      $danger: #f36e60;
      $light: #f5fbfb;
      $dark: #040b0c;
      
      $link-hover-decoration: none;
      $border-radius: 0;
      $font-family-sans-serif: "Fira Sans", sans-serif;
      $font-family-monospace: "Fira Mono", monospace;
      $font-weight-bold: 600;
      
      @import "~bootstrap/scss/functions";
      @import "~bootstrap/scss/variables";
      @import "~bootstrap/scss/mixins";
      @import "~bootstrap/scss/root";
      @import "~bootstrap/scss/reboot";
      @import "~bootstrap/scss/type";
      @import "~bootstrap/scss/images";
      // @import "~bootstrap/scss/code";
      @import "~bootstrap/scss/grid";
      @import "~bootstrap/scss/tables";
      @import "~bootstrap/scss/forms";
      @import "~bootstrap/scss/buttons";
      @import "~bootstrap/scss/transitions";
      @import "~bootstrap/scss/dropdown";
      @import "~bootstrap/scss/button-group";
      // @import "~bootstrap/scss/input-group";
      @import "~bootstrap/scss/custom-forms";
      @import "~bootstrap/scss/nav";
      @import "~bootstrap/scss/navbar";
      @import "~bootstrap/scss/card";
      @import "~bootstrap/scss/breadcrumb";
      // @import "~bootstrap/scss/pagination";
      // @import "~bootstrap/scss/badge";
      @import "~bootstrap/scss/jumbotron";
      // @import "~bootstrap/scss/alert";
      // @import "~bootstrap/scss/progress";
      // @import "~bootstrap/scss/media";
      @import "~bootstrap/scss/list-group";
      // @import "~bootstrap/scss/close";
      // @import "~bootstrap/scss/toasts";
      // @import "~bootstrap/scss/modal";
      // @import "~bootstrap/scss/tooltip";
      // @import "~bootstrap/scss/popover";
      // @import "~bootstrap/scss/carousel";
      // @import "~bootstrap/scss/spinners";
      @import "~bootstrap/scss/utilities";
      // @import "~bootstrap/scss/print";
      
      1. Import the style in src/App.vue:
      @import "./assets/custom-bootstrap.scss";
      
      1. Create a page, e.g. in src/views/bootstrap.vue. Here I will create a page with nav, about, and contact sections.
      <template>
        <div>
          <h1>Bootstrap Demo</h1>
      
          <BootstrapNav />
          <BootstrapAbout />
          <BootstrapContact />
        </div>
      </template>
      
      <script>
      import BootstrapAbout from "@/components/BootstrapAbout";
      import BootstrapContact from "@/components/BootstrapContact";
      import BootstrapNav from "@/components/BootstrapNav";
      
      export default {
        components: {
          BootstrapAbout,
          BootstrapContact,
          BootstrapNav
        }
      };
      </script>
      

      In src/components/BootstrapNav.vue:

        <template>
          <b-navbar toggleable="lg" type="dark" variant="dark" class="w-100">
            <b-navbar-brand to="/">
              <b-img
                class="d-inline-block align-top"
                :src="require('../assets/logo.svg')"
                alt="Logo"
                width="30"
                height="30"
              />
              <span class="font-weight-bold">Unordinary</span>
            </b-navbar-brand>
        
            <b-navbar-toggle target="nav-collapse"></b-navbar-toggle>
        
            <b-collapse id="nav-collapse" is-nav>
              <b-navbar-nav>
                <b-nav-item v-for="(item, index) in menu" :key="index" :href="item.to">
                  {{ item.label }}
                </b-nav-item>
              </b-navbar-nav>
            </b-collapse>
          </b-navbar>
        </template>
        
        <script>
        export default {
          data() {
            return {
              menu: [
                { to: "#about", label: "About" },
                { to: "#contact", label: "Contact" }
              ]
            };
          }
        };
        </script>
        
        <template>
          <nav class="bg-dark navbar navbar-expand-lg navbar-dark">
            <router-link class="navbar-brand" to="/">
              <img
                :src="require('../assets/logo.svg')"
                class="d-inline-block align-top"
                alt="Logo"
                width="30"
                height="30"
              />
              <span class="font-weight-bold">Unordinary</span>
            </router-link>
        
            <button
              aria-controls="navbarNav"
              aria-expanded="false"
              aria-label="Toggle navigation"
              class="navbar-toggler"
              data-target="#navbarNav"
              data-toggle="collapse"
              type="button"
            >
              <span class="navbar-toggler-icon"></span>
            </button>
        
            <div id="navbarNav" class="collapse navbar-collapse">
              <ul class="navbar-nav ml-auto w-auto">
                <li v-for="(item, index) in menu" :key="index" class="nav-item">
                  <a class="nav-link" :href="item.to">
                    {{ item.label }}
                  </a>
                </li>
              </ul>
            </div>
          </nav>
        </template>
        
        <script>
        export default {
          data() {
            return {
              menu: [
                { to: "#about", label: "About" },
                { to: "#contact", label: "Contact" }
              ]
            };
          }
        };
        </script>
        
        // Make sure to add code blocks to your code group

        In src/components/BootstrapAbout.vue:

          <template>
            <b-jumbotron id="about" bg-variant="white" class="rounded-0 mb-0">
              <b-row>
                <b-col
                  md="4"
                  order-md="2"
                  class="d-flex align-items-center justify-content-center"
                >
                  <b-img
                    fluid
                    :src="require('../assets/john-doe.jpeg')"
                    alt="John Doe"
                    class="img"
                  />
                </b-col>
          
                <b-col md="8" order-md="1">
                  <b-container>
                    <h2 class="display-4">John Doe</h2>
          
                    <p class="lead">
                      I am also known as joker, <del>shadow</del> king, and
                      &#647;n&#477;sp&#592;&#654;.<br />I hate the hierarchy, so I broke
                      it.
                    </p>
                  </b-container>
                </b-col>
              </b-row>
            </b-jumbotron>
          </template>
          
          <style lang="scss" scoped>
          .img {
            max-height: 300px;
          }
          </style>
          
          <template>
            <div id="about" class="bg-white rounded-0 jumbotron mb-0 row">
              <div
                class="col-md-4 order-md-2 d-flex align-items-center justify-content-center"
              >
                <img
                  :src="require('../assets/john-doe.jpeg')"
                  alt="John Doe"
                  class="img-fluid"
                />
              </div>
          
              <div class="col-md-8 order-md-1 container">
                <h2 class="display-4">John Doe</h2>
          
                <p class="lead">
                  I am also known as joker, <del>shadow</del> king, and
                  &#647;n&#477;sp&#592;&#654;.<br />I hate the hierarchy, so I broke it.
                </p>
              </div>
            </div>
          </template>
          
          <style scoped>
          img {
            max-height: 300px;
          }
          </style>
          
          // Make sure to add code blocks to your code group

          In src/components/BootstrapContact.vue:

            <template>
              <b-container
                id="contact"
                fluid
                bg-variant="primary"
                class="bg-primary mh-100 px-0 text-white"
              >
                <b-container fluid class="content py-3 mh-100">
                  <b-container>
                    <h3 class="mb-4">Contact Me</h3>
            
                    <p>
                      You know I am busy teaching people lessons, so reach me through my
                      sidekick <del>Cecile</del> <ins>Zeke</ins>.
                    </p>
            
                    <hr class="bg-white" />
            
                    <b-row>
                      <b-col md="7" class="mb-5 mb-md-0 py-3">
                        <b-form
                          action="https://formspree.io/yasmin@yasminzy.com"
                          method="POST"
                        >
                          <b-form-group>
                            <b-form-input
                              id="name"
                              class="form-control"
                              type="text"
                              name="name"
                              placeholder="Name"
                              required
                            />
                          </b-form-group>
            
                          <b-form-group>
                            <b-form-input
                              id="email"
                              class="form-control"
                              type="email"
                              name="_replyto"
                              aria-describedby="emailHelp"
                              placeholder="Email"
                              required
                            />
                          </b-form-group>
            
                          <b-form-group>
                            <b-form-textarea
                              id="message"
                              class="form-control"
                              rows="3"
                              name="message"
                              placeholder="Message"
                              required
                            />
                          </b-form-group>
            
                          <input type="hidden" name="_subject" value="Bootstrap Demo" />
                          <input
                            type="hidden"
                            name="_next"
                            value="https://www.yasminzy.com"
                          />
            
                          <b-button
                            type="submit"
                            class="bg-white btn d-flex align-items-center text-dark"
                          >
                            SEND
                          </b-button>
                        </b-form>
                      </b-col>
            
                      <b-col md="3" offset-md="1">
                        <b-list-group class="mb-5">
                          <b-list-group-item
                            v-for="(item, index) in contact"
                            :key="index"
                            class="bg-transparent border-left-0 border-right-0 border-top-0 px-0"
                          >
                            <div>
                              <p class="font-weight-bold mb-2 text-uppercase">
                                {{ item.label }}
                              </p>
            
                              <small>{{ item.content }}</small>
                            </div>
                          </b-list-group-item>
                        </b-list-group>
                      </b-col>
                    </b-row>
                  </b-container>
                </b-container>
              </b-container>
            </template>
            
            <script>
            export default {
              data() {
                return {
                  contact: [
                    {
                      label: "Telephone",
                      content: "(12) 345-6789"
                    },
                    {
                      label: "Email",
                      content: "king[at]welston.com"
                    },
                    {
                      label: "Address",
                      content: "2020 Black Speech Bubble, ID"
                    }
                  ]
                };
              }
            };
            </script>
            
            <template>
              <div id="contact" class="bg-primary container-fluid mh-100 px-0 text-white">
                <div class="container-fluid content py-3 mh-100">
                  <div class="container">
                    <h3 class="mb-4">Contact Me</h3>
            
                    <p>
                      You know I am busy teaching people lessons, so reach me through my
                      sidekick <del>Cecile</del> <ins>Zeke</ins>.
                    </p>
            
                    <hr class="bg-white" />
            
                    <div class="row">
                      <div class="col-md-7 mb-5 mb-md-0 py-3">
                        <form
                          action="https://formspree.io/yasmin@yasminzy.com"
                          method="POST"
                        >
                          <div class="form-group">
                            <input
                              id="name"
                              class="form-control"
                              type="text"
                              name="name"
                              placeholder="Name"
                              required
                            />
                          </div>
            
                          <div class="form-group">
                            <input
                              id="email"
                              class="form-control"
                              type="email"
                              name="_replyto"
                              aria-describedby="emailHelp"
                              placeholder="Email"
                              required
                            />
                          </div>
            
                          <div class="form-group">
                            <textarea
                              id="message"
                              class="form-control"
                              rows="3"
                              name="message"
                              placeholder="Message"
                              required
                            />
                          </div>
            
                          <input type="hidden" name="_subject" value="Bootstrap Demo" />
                          <input
                            type="hidden"
                            name="_next"
                            value="https://www.yasminzy.com"
                          />
            
                          <button
                            type="submit"
                            class="bg-white btn d-flex align-items-center text-dark"
                          >
                            SEND
                          </button>
                        </form>
                      </div>
            
                      <div class="col-md-3 offset-md-1">
                        <ul class="list-group mb-5 wrapper">
                          <li
                            v-for="(item, index) in contact"
                            :key="index"
                            class="bg-transparent border-left-0 border-right-0 border-top-0 list-group-item px-0"
                          >
                            <div>
                              <p class="font-weight-bold mb-2 text-uppercase">
                                {{ item.label }}
                              </p>
            
                              <small>{{ item.content }}</small>
                            </div>
                          </li>
                        </ul>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </template>
            
            <script>
            export default {
              data() {
                return {
                  contact: [
                    {
                      label: "Telephone",
                      content: "(12) 345-6789"
                    },
                    {
                      label: "Email",
                      content: "king[at]welston.com"
                    },
                    {
                      label: "Address",
                      content: "2020 Black Speech Bubble, ID"
                    }
                  ]
                };
              }
            };
            </script>
            
            <style lang="scss" scoped>
            h2 {
              text-align: center;
            
              @media (min-width: 768px) {
                text-align: initial;
              }
            }
            
            li {
              text-align: center;
            
              @media (min-width: 768px) {
                text-align: initial;
              }
            }
            
            li:last-child {
              border-bottom: 0;
            }
            </style>
            
            // Make sure to add code blocks to your code group
            Last updated: 11/1/2020, 3:28:11 PM