1

I am trying to use Bootstrap 5's "collapse" component on a button, but I am unsure how to actually use it with VueJS2

I have a single file component like so:

<template> section:

          <button
            class="btn btn-danger"
            type="button"
            data-bs-toggle="collapse"
            data-bs-target="#collapseExample"
            aria-expanded="false"
            aria-controls="collapseExample"
          >
            Mark As Rejected
          </button>
          <div class="collapse" id="collapseExample">
            <div class="card card-body">
              Some placeholder content for the collapse component. This panel is
              hidden by default but revealed when the user activates the
              relevant trigger.
            </div>
          </div>

<script> section:

<script>
import Collapse from 'bootstrap/js/dist/collapse'
export default {
    ...
    methods: {
        // how to manually enable the collapse via JavaScript???
    }
}
    ...
</script>

The Bootstrap docs had an example of using vanilla JavaScript...but how to do it with VueJS?

Bootstrap 5 Collapse native JavaScript example:

var collapseElementList = [].slice.call(document.querySelectorAll('.collapse'))
var collapseList = collapseElementList.map(function (collapseEl) {
  return new bootstrap.Collapse(collapseEl)
})
redshift
  • 4,815
  • 13
  • 75
  • 138

3 Answers3

0

There are many ways you could do it. The simplest way to use the Bootstrap JS inside a Vue method. For example...

    mounted() {
        this.openCollapse()
    },
    methods: {
        openCollapse() {
            var collapseElementList = [].slice.call(document.querySelectorAll('.collapse'))
            var collapseList = collapseElementList.map(function (collapseEl) {
              var bsCollapse = new bootstrap.Collapse(collapseEl)
              bsCollapse.show()
            })
        }
    }

Demo


Or, you could turn the Bootstrap Collapse component into a reusable Vue component...

const collapse = Vue.component('bsCollapse', {
    template: `
        <div>
            <slot name="trigger"></slot>
            <slot name="target"></slot>
        </div>
    `,
    props: {
        toggle: {
            required: false,
            default: false
        },
        id: {
            required: true
        }
    },
    mounted() {
        var trigger = this.$slots['trigger'][0].elm
        var target = this.$slots['target'][0].elm
        target.classList.add('collapse')
        target.setAttribute('id', this.id);
        trigger.setAttribute('data-bs-target', '#' + this.id);
        trigger.setAttribute('data-bs-toggle','collapse');
        new Collapse(target, {toggle: this.toggle })
    },
})

And use it like...

    <bs-collapse id="collapse1">
            <button class="btn btn-info" slot="trigger">
                Bootstrap collapse
            </button>
            <div slot="target">Toggle the display of this collapsible content!</div>
    </bs-collapse>

Also see: Using Bootstrap 5 with Vue 3

Carol Skelly
  • 351,302
  • 90
  • 710
  • 624
0

I was simply overthinking this.

All I had to do in order to use Collapse in VueJS single file components with the HTML data-attributes was to simply import the Collapse file like so:

import 'bootstrap/js/dist/collapse'

This would also allow for easy tree-shaking, as I would only need to import the scripts when needed.

redshift
  • 4,815
  • 13
  • 75
  • 138
-2

I faced this problem myself and solved it this way

  1. Install "@popperjs/core" and "bootstrap"
{
    "devDependencies": {

        ....
        
        "@popperjs/core": "^2.10",
        "bootstrap": "^5.1.3"
    }
}
  1. Importing Class
import { Collapse } from 'bootstrap'
  1. Add "ref" to an element by class "navbar-collapse"
ref="menuCollapse"
  1. Calling a class with a parameter
new Collapse(this.$refs.menuCollapse, { toggle: false })

Complete component code example

<template>
    <nav class="navbar navbar-expand-lg navbar-light bg-light">
        <div class="container-fluid">
            <button
                class="navbar-toggler"
                type="button"
                data-bs-toggle="collapse"
                data-bs-target="#navbarTogglerDemo01"
                aria-controls="navbarTogglerDemo01"
                aria-expanded="false"
                aria-label="Toggle navigation"
            >
                <span class="navbar-toggler-icon"></span>
            </button>
            <a class="navbar-brand" href="#">Foo brand</a>
            <div ref="menuCollapse" class="collapse navbar-collapse" id="navbarTogglerDemo01" >
                <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                    <li class="nav-item">
                        <a class="nav-link active" aria-current="page" href="#">Bar</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link active" aria-current="page" href="#">Bas</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>
</template>

<script>
import { Collapse } from 'bootstrap'

export default {
    mounted() {
        // eslint-disable-next-line no-new
        new Collapse(this.$refs.menuCollapse, { toggle: false })
    },
}
</script>