Using Bootstrap 5 with Vue 3 - vuejs3

I want to use Bootstrap 5 with Vue 3. As Bootstrap 5 uses vanilla JS (no JQuery), can I use Bootstrap 5 directly in a Vue 3 project (without using Bootstrap-Vue)? Can someone guide me how to use Bootstrap 5 with Vue 3?

Bootstrap 5 no longer needs jQuery so it's easier to use with Vue, and no longer requires a library like bootstrap-vue.
Install bootstrap as you would any other JS module in the Vue project using npm install or by adding it to the package.json...
npm install --save bootstrap
npm install --save #popperjs/core
Next, add the Bootstrap CSS and JS components to the Vue project entrypoint (ie: src/main.js)...
import "bootstrap/dist/css/bootstrap.min.css"
import "bootstrap"
Then, the simplest way to use Bootstrap components is via the data-bs- attributes. For example here's the Bootstrap Collapse component...
<button
class="btn btn-primary"
data-bs-target="#collapseTarget"
data-bs-toggle="collapse">
Bootstrap collapse
</button>
<div class="collapse py-2" id="collapseTarget">
This is the toggle-able content!
</div>
Demo with Navbar component
Or, you can import any Bootstrap components and "wrap" them as Vue components. For example here's the Popover component...
import { Popover } from bootstrap;
const popover = Vue.component('bsPopover', {
template: `
<slot/>
`,
props: {
content: {
required: false,
default: '',
},
title: {
default: 'My Popover',
},
trigger: {
default: 'click',
},
delay: {
default: 0,
},
html: {
default: false,
},
},
mounted() {
// pass bootstrap popover options from props
var options = this.$props
var ele = this.$slots.default[0].elm
new Popover(ele,options)
},
})
<bs-popover
title="Hello Popover"
content="This is my content for the popover!"
trigger="hover">
<button class="btn btn-danger">
Hover for popover
</button>
</bs-popover>
Demo |
Read more

Yes, you can use Bootstrap without Bootstrap-Vue.
Install these two packages with npm:
npm install --save #popperjs/core bootstrap#next
Import Bootstrap to src/main.js:
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap";
Example usage for Vue Template:
<div class="dropdown">
<button
class="btn btn-secondary dropdown-toggle"
type="button"
id="dropdownMenuButton1"
data-bs-toggle="dropdown"
aria-expanded="false"
>
Check Bootstrap
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</div>
Result:

While the Bootstrap CSS can be used with any framework (React, Vue, Angular, etc), the Bootstrap JavaScript is not fully compatible with them.
Here's the official reasoning from the Bootstrap 5 docs:
While the Bootstrap CSS can be used with any framework, the Bootstrap JavaScript is not fully compatible with JavaScript frameworks like React, Vue, and Angular which assume full knowledge of the DOM. Both Bootstrap and the framework may attempt to mutate the same DOM element, resulting in bugs like dropdowns that are stuck in the “open” position.
The docs state to use an alternative framework-specific package instead of the Bootstrap JavaScript such as React Bootstrap, BootstrapVue, and ng-bootstrap.
Unfortunately, BootstrapVue is only compatible with Vue2/Nuxt2 and there is no version available for Vue3/Nuxt3 yet.

It's easy to implement this once you understand how Bootstrap modals work. Bootstrap modals have a div element with a class of modal fade. When it is triggered, this element gets the show and d-block class as well. In addition, the body tag gets an additional class of modal-open. When the modal is closed, this process is reversed. Understanding this, we can easily implement Bootstrap 5 modals in one's code:
Import Bootstrap 5's CDN in your code. Add both the CSS and JS to your code.
Our sample Single Page Component will look like this:
<template>
<div>
<p>Test modalnow</p>
<div>
<button type="button" class="btn btn-primary" #click="modalToggle">My Modal</button>
<div
ref="modal"
class="modal fade"
:class="{ show: active, 'd-block': active }"
tabindex="-1"
role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button
type="button"
class="close"
data-dismiss="modal"
aria-label="Close"
#click="modalToggle">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Modal body text goes here.</p>
</div>
</div>
</div>
</div>
<div v-if="active" class="modal-backdrop fade show"></div>
</div>
</div>
</template>
Here we are using the basic Bootstrap 5 modal.
<script>
export default {
data() {
return {
active: false,
}
},
methods: {
modalToggle() {
const body = document.querySelector("body")
this.active = !this.active
this.active ? body.classList.add("modal-open") : body.classList.remove("modal-open")
},
},
}
</script>
Here, we have a variable active which is initially set false. So modal will not show up on page load. On clicking a link, we use a method to toggle this variable. This will remove the show attribute and the d-block class from our modalm and remove the modal-open property from the body tag.

bootstrap 5 must have popper for run , try with this npm :
npm install --save bootstrap
npm i #popperjs/core

please add this package :
npm install --save #popperjs/core

To make bootstrap work with SSR you can not:
import "bootstrap";
as others have suggested since it will give you an error:
document is not defined
This is not an optimal solution but it will work
npm install bootstrap
And only import the bootstrap scss in your styles tag so you have access to the bootstrap variables etc.
<style lang="scss">
#import 'bootstrap/scss/bootstrap';
.sticky-sidebar {
z-index: $zindex-sticky;
...
}
</style>
And then just add the bootstrap bundle to your header. Note: you don't have to add the css now that it is imported in your component.

Related

Vue.js 3 - JS from imported Bootstrap 5 does not work, CSS works fine [duplicate]

I want to use Bootstrap 5 with Vue 3. As Bootstrap 5 uses vanilla JS (no JQuery), can I use Bootstrap 5 directly in a Vue 3 project (without using Bootstrap-Vue)? Can someone guide me how to use Bootstrap 5 with Vue 3?
Bootstrap 5 no longer needs jQuery so it's easier to use with Vue, and no longer requires a library like bootstrap-vue.
Install bootstrap as you would any other JS module in the Vue project using npm install or by adding it to the package.json...
npm install --save bootstrap
npm install --save #popperjs/core
Next, add the Bootstrap CSS and JS components to the Vue project entrypoint (ie: src/main.js)...
import "bootstrap/dist/css/bootstrap.min.css"
import "bootstrap"
Then, the simplest way to use Bootstrap components is via the data-bs- attributes. For example here's the Bootstrap Collapse component...
<button
class="btn btn-primary"
data-bs-target="#collapseTarget"
data-bs-toggle="collapse">
Bootstrap collapse
</button>
<div class="collapse py-2" id="collapseTarget">
This is the toggle-able content!
</div>
Demo with Navbar component
Or, you can import any Bootstrap components and "wrap" them as Vue components. For example here's the Popover component...
import { Popover } from bootstrap;
const popover = Vue.component('bsPopover', {
template: `
<slot/>
`,
props: {
content: {
required: false,
default: '',
},
title: {
default: 'My Popover',
},
trigger: {
default: 'click',
},
delay: {
default: 0,
},
html: {
default: false,
},
},
mounted() {
// pass bootstrap popover options from props
var options = this.$props
var ele = this.$slots.default[0].elm
new Popover(ele,options)
},
})
<bs-popover
title="Hello Popover"
content="This is my content for the popover!"
trigger="hover">
<button class="btn btn-danger">
Hover for popover
</button>
</bs-popover>
Demo |
Read more
Yes, you can use Bootstrap without Bootstrap-Vue.
Install these two packages with npm:
npm install --save #popperjs/core bootstrap#next
Import Bootstrap to src/main.js:
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap";
Example usage for Vue Template:
<div class="dropdown">
<button
class="btn btn-secondary dropdown-toggle"
type="button"
id="dropdownMenuButton1"
data-bs-toggle="dropdown"
aria-expanded="false"
>
Check Bootstrap
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</div>
Result:
While the Bootstrap CSS can be used with any framework (React, Vue, Angular, etc), the Bootstrap JavaScript is not fully compatible with them.
Here's the official reasoning from the Bootstrap 5 docs:
While the Bootstrap CSS can be used with any framework, the Bootstrap JavaScript is not fully compatible with JavaScript frameworks like React, Vue, and Angular which assume full knowledge of the DOM. Both Bootstrap and the framework may attempt to mutate the same DOM element, resulting in bugs like dropdowns that are stuck in the “open” position.
The docs state to use an alternative framework-specific package instead of the Bootstrap JavaScript such as React Bootstrap, BootstrapVue, and ng-bootstrap.
Unfortunately, BootstrapVue is only compatible with Vue2/Nuxt2 and there is no version available for Vue3/Nuxt3 yet.
It's easy to implement this once you understand how Bootstrap modals work. Bootstrap modals have a div element with a class of modal fade. When it is triggered, this element gets the show and d-block class as well. In addition, the body tag gets an additional class of modal-open. When the modal is closed, this process is reversed. Understanding this, we can easily implement Bootstrap 5 modals in one's code:
Import Bootstrap 5's CDN in your code. Add both the CSS and JS to your code.
Our sample Single Page Component will look like this:
<template>
<div>
<p>Test modalnow</p>
<div>
<button type="button" class="btn btn-primary" #click="modalToggle">My Modal</button>
<div
ref="modal"
class="modal fade"
:class="{ show: active, 'd-block': active }"
tabindex="-1"
role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button
type="button"
class="close"
data-dismiss="modal"
aria-label="Close"
#click="modalToggle">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>Modal body text goes here.</p>
</div>
</div>
</div>
</div>
<div v-if="active" class="modal-backdrop fade show"></div>
</div>
</div>
</template>
Here we are using the basic Bootstrap 5 modal.
<script>
export default {
data() {
return {
active: false,
}
},
methods: {
modalToggle() {
const body = document.querySelector("body")
this.active = !this.active
this.active ? body.classList.add("modal-open") : body.classList.remove("modal-open")
},
},
}
</script>
Here, we have a variable active which is initially set false. So modal will not show up on page load. On clicking a link, we use a method to toggle this variable. This will remove the show attribute and the d-block class from our modalm and remove the modal-open property from the body tag.
bootstrap 5 must have popper for run , try with this npm :
npm install --save bootstrap
npm i #popperjs/core
please add this package :
npm install --save #popperjs/core
To make bootstrap work with SSR you can not:
import "bootstrap";
as others have suggested since it will give you an error:
document is not defined
This is not an optimal solution but it will work
npm install bootstrap
And only import the bootstrap scss in your styles tag so you have access to the bootstrap variables etc.
<style lang="scss">
#import 'bootstrap/scss/bootstrap';
.sticky-sidebar {
z-index: $zindex-sticky;
...
}
</style>
And then just add the bootstrap bundle to your header. Note: you don't have to add the css now that it is imported in your component.

Rails 6 GlideJS carousel issues (without jquery)

I have been looking for a way to remove the need for jQuery in my project. The carousel is my last bastion of jQuery, so I am trying to set up GlideJS for a carousel with does not rely on jQuery. When I run new Glide({}) in rails console I get NoMethodError (undefined method 'Glide' for main:Object)
If I look at the errors in the dev tools in firefox I am seeing [Glide warn]: Root element must be a existing Html node / Uncaught TypeError: this.root is undefined.
application.js
require("#rails/ujs").start()
require("turbolinks").start()
require("channels")
import 'controllers'
import "bootstrap"
import Glide from '#glidejs/glide'
new Glide('.glide').mount()
frontpage.html.erb
<div class="glide">
<div class="glide__track" data-glide-el="track">
<ul class="glide__slides">
<li class="glide__slide">slide1</li>
<li class="glide__slide">slide2</li>
<li class="glide__slide">slide3</li>
<li class="glide__slide">slide4</li>
</ul>
</div>
<div class="glide__arrows" data-glide-el="controls">
<button class="glide__arrow glide__arrow--left" data-glide-dir="<"><</button>
<button class="glide__arrow glide__arrow--right" data-glide-dir=">">></button>
</div>
</div>
I have not worked with much, if any, javascript in my projects to date.
As I am not savy on JS, this was given to me and it worked.
In the application.js
document.addEventListener("turbolinks:load", () => {
new Glide('.glide', {
}).mount()
})

Adding Bootstrap CSS along with CSS Module in classname in React

I want to combine the react js bootstrap classes for my button along with my positioning css from my css module for the button but am not able to combine both to work.
<button className= {'btn btn-primary ${styles.bottomButton}} onClick={(e) => logout(e)}>
First, you need to import the CSS file like this:
import classes from "./Navbar.module.css";
Then, you can use that in below way (using template literals or backticks):
className={`navbar navbar-expand-lg navbar-light bg-light ${classes.mainnavbar}`}
Got it using
<button className= {'btn btn-primary' + ' ' + styles.bottomButton} onClick={(e) => logout(e)}>
If you want to apply styles easily, you can use the patch-styles package. For more advanced usage, see the example in StackBlitz. It's introducing a more declarative way for applying styles; you need to wrap your code with <PatchStyles classNames={styles}> where styles is the default import the style module.
With all that you can just write:
<PatchStyles classNames={styles}>
<button className="btn btn-primary bottomButton" onClick={(e) => logout(e)}>...</button>
</PatchStyles>
You can make use of the backticks introduced in ES2015.
className={`btn btn-primary ${styles.bottomButton}`}

Using Foundation 6.3 in Meteor

I've added the Meteor package foundation zurb:foundation-sites. This is using v.6.3 (I couldn't get the npm package to work using v6.4.1)
I've got my main.scss file importing:
#import '{zurb:foundation-sites}/scss/foundation';
#include foundation-everything;
My Templates:
Template.myReveal.onRendered(function () {
this.myRevealInstance = new Foundation.Reveal($('#myReveal'));
});
Template.myReveal.onDestroyed(function () {
let reveal = this.myRevealInstance;
if (reveal) {
reveal.destroy();
}
});
My html:
<template name="myReveal">
<p><button class="button" data-toggle="myReveal">Click me for a modal</button></p>
<div class="reveal" id="myReveal" data-reveal data-animation-in="fade-in" data-animation-out="fade-out">
<h1>Awesome</h1>
<p class="lead">Your couch. It is mine.</p>
<p>I'm a cool paragraph that lives inside of an even cooler modal. Wins!</p>
<button class="close-button" data-close aria-label="Close reveal" type="button">
<span aria-hidden="true">×</span>
</button>
</div>
The animation plug-in isn't working. I've tried using:
Template.myReveal.onRendered(function () {
$(document).foundation();
});
But no luck. I tried adding the zurb:motion.ui package and still no luck. How can I get the animations to work?

How to change NgbCollapse default value of false?

The default value for ngbCollapse is false, as described at https://ng-bootstrap.github.io/#/components/collapse. The example given there uses the following code: https://ng-bootstrap.github.io/app/components/collapse/demos/basic/plnkr.html
<p>
<button type="button" class="btn btn-outline-primary" (click)="isCollapsed = !isCollapsed"
[attr.aria-expanded]="!isCollapsed" aria-controls="collapseExample">
Toggle
</button>
</p>
<div id="collapseExample" [ngbCollapse]="isCollapsed">
<div class="card">
<div class="card-block">
You can collapse this card by clicking Toggle
</div>
</div>
</div>
How does one over-ride the default so that the toolbar is collapsed by default?
Noticed the same thing. Initialize the variable in a constructor and it works fine.
export class AppComponent {
isCollapsed:boolean;
constructor() {
this.isCollapsed = true;
}
Modifying this within the Typescript seems to drive away from the intent of using the module's provided properties. Instead, by utilize [ngbCollapse] you do not need add to Typescript and have more control with the advantage of ngDirectives.
<div id="collapseExample" [ngbCollapse]="!isCollapsed">
Additionally, when used within dynamically generated content (*ngFor...[ngbCollapse]=) you can take advantage of ng-if-else conditional states
*ngIf="getIsEditing(buffer); then tableEdit; else tableView;"

Resources