BootstrapVue Load Modal JavaScript Dynamically Only When Shown (Nuxt)

April 12, 2022

To only load b-modal JavaScript dynamically when the modal is shown, we need to wrap the modal in a component.

Create components/LinkFormModal.vue

  • I already have components/LinkForm.vue which is the content of the modal.
  • The code for ModalPlugin, OverlayPlugin and components/LinkForm.vue is dynamically loaded over the network only when this component/modal is shown
<template>
  <b-modal v-model="localShow" size="lg" title="Link" :no-close-on-backdrop="true" @ok="saveLink" style="z-index:2;" :body-class="busy ? 'position-static' : ''">
    <b-overlay :show="busy" no-wrap></b-overlay>
    <link-form ref="linkForm" :item="link"  />
  </b-modal>
</template>

<script>
import Vue from 'vue'
import { ModalPlugin, OverlayPlugin } from 'bootstrap-vue'
Vue.use(ModalPlugin)
Vue.use(OverlayPlugin)

export default {
  props: ['value', 'link'],
  data() {
    return {
      localShow: this.value,
      busy: false
    }
  },
  methods: {
    close() {
      // this.$emit('update:value', false)
      this.$emit('input', false)
    },
    async saveLink(bvModalEvent) {
      bvModalEvent.preventDefault()

      this.busy = true

      // perform action

      // call this when done / completed
      this.close()
    },
  },
  watch: {
    value(value) {
      this.localShow = value
    },
    localShow(value) {
      // this.$emit('update:value', value)
      this.$emit('input', value)
    }
  },
  mounted() {
    // since this component is dynamically loaded over the network, call the following to end loading animation
    this.$nuxt.$loading.finish()
  }
}
</script>

Usage

<template>
  <client-only>
     <lazy-link-form-modal v-model="linkModal" v-if="linkModal" :link="link"></lazy-t-link-form-modal>
  </client-only>
</template>

<script>
export default {
  data() {
    return {
      link: {},
      linkModal: false,
    }
  },
  methods: {
    showLinkModal() {
      // start loading animation as link-form-modal code is loaded dynamically over the network
      this.$nuxt.$loading.start()

      this.linkModal = true
    }
  }
}  
</script>

NOTE: If you only want to dynamically load the content (components/LinkForm.vue) but pre-load b-modal, refer to BootstrapVue Modal Lazy Load / Dynamic Load Content (Reduce Bundle Size) in Nuxt.js.

This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.