Search code examples
vue.jstabslazy-initializationbootstrap-vue

VueJs Lazy initialization of tab's component just once


I'm trying to make the bootstrap-vue tabs initialization lazy and though it works if i set the lazy attribute on true, it render the component every time i'm visiting a specific tab:

BtabsWrapper.vue:

<b-tabs
    :lazy="true"
  >
    <b-tab
      v-for="(tab, index) in tabs"
      :key="'li-tab-' + index"
      :title="tab.title"
      :href="'#' + tab.id"
    >
      <slot
        :name="tab.id"
      />
    </b-tab>
  </b-tabs>

I need more of a lazy initialization of each tab(just once) rather than re rendering the tab's component every time the user visits it. Any ideas?


Solution

  • If you wrap the content of each tab in a v-if and change that condition once when they're loaded you should get your desired outcome.

    And in your case if you're using a v-for, you can utilize the index in your v-for in the includes part as visitedTabs.includes(index)

    window.onload = () => {
      new Vue({
        el: '#app',
        data() {
          return {
            visitedTabs: []
          }
        },
        methods: {
          onInput(value) {
            if(!this.visitedTabs.includes(value)){
              this.visitedTabs.push(value)
            }
          }
        }
      })
    }
    body {
      padding: 1em;
    }
    <link href="https://unpkg.com/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
    <link href="https://unpkg.com/[email protected]/dist/bootstrap-vue.css" rel="stylesheet"/>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/bootstrap-vue.js"></script>
    
    <div id="app">
      <b-card clas no-body>
        <b-tabs card @input="onInput">
          <b-tab title="First tab">
            <div v-if="visitedTabs.includes(0)">
              Hello World
            </div>
          </b-tab>
          <b-tab title="Second tab">
            <div v-if="visitedTabs.includes(1)">
              <b-input />
            </div>
          </b-tab>
          <b-tab title="Third tab">
            <div v-if="visitedTabs.includes(2)">
              <b-checkbox />
            </div>
          </b-tab>
        </b-tabs>
      </b-card>
    </div>