Bootstrap 5 - offcanvas component not displayed in vue 3 app

2.4k views Asked by At

I'm trying to integrate the new offcanvas component of bootstrap 5 in my vue app. I have this code and after the app is build I'm tying to test it but I'm not able to see the offcanvas menu. I don't have loaded the js plugin to mantain my app light and I'm adding the show class using a variable that will bind the needed class. How I can fix it?

<template>
  <nav class="navbar navbar-collapse bg-light fixed-top">
    <div class="container">
      <span class="float-start">
        <button class="navbar-toggler" type="button" @click.prevent="showOffcanvasMenu()">
          <span class="navbar-toggler-icon"></span>
        </button>
      </span>
    </div>
    <div class="offcanvas offcanvas-start" :class="showMenu ? '' : 'show'" tabindex="-1">
      <div class="offcanvas-header">
        <h5 class="offcanvas-title" id="">Offcanvas with backdrop</h5>
        <button type="button" class="btn-close text-reset" @click.prevent="showOffcanvasMenu()"></button>
      </div>
      <div class="offcanvas-body">
        <p>.....</p>
      </div>
    </div>
  </nav>
  
  <!-- <div class="container-fluid bg-light p-0" v-show="isLoading">
    <div class="row">
      <div class="col-12 text-center">
        <div class="spinner-grow text-primary" role="status">
          <span class="visually-hidden">Loading...</span>
        </div>    
      </div>
    </div>
  </div> -->

  <router-view/>
</template>

<script>

export default {
  name: 'App',
  data(){
    return {
      showMenu: false
    }
  },
  methods: {
    showOffcanvasMenu(){
      this.showMenu ? this.showMenu = false : this.showMenu = true;
    }
  }
}
</script>

<style lang="scss">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  //color: #2c3e50;
}
</style>
1

There are 1 answers

3
Carol Skelly On BEST ANSWER

I see a few issues.

First, the :class conditional logic is reversed, it should be:

:class="showMenu ? 'show' : ''" 

Secondly (the larger issue), is that simply toggling the show class isn't going to work to control display of the Offcanvas element. The Offcanvas JS component does more than toggle the show class. It also changes the visibility property and hooks up several other methods/events.

Workarounds

1 - One option would be to not use Vue to toggle the Offcanvas element and simply use the vanilla JS data-bs- attributes.

or,

2 - Another option is to also toggle the visibility property of the element based on the value of showMenu...

:style="{ visibility: showMenu ? 'visible' : 'hidden' }

Demo

or,

3 - Create a Vue wrapper component for Bootstrap's Offcanvas component.