Skip to content
Advertisement

Vue js load modal content with ajax

I’m using vue js with laravel, In my page i have 13 modals, I thing it’s not a good idea to insert 13 modals in the same page so i put this in my blade :

<modal v-if="showModal" @close="showModal = false">
     <header slot="header" v-html="modalHeader"></header>
     <component slot="body" :is="currentBody"></component>
</modal>

And in my file.js i have this :

Vue.component('modal', require('./components/Modal.vue'));
Vue.component('StatusModal', require('./components/modals/StatusModal.vue'));
Vue.component('UserModal', require('./components/modals/UserModal.vue'));

const profile = new Vue({
    el: '#profile',
    data: {
        showModal: false,
        modalHeader: '',
        currentBody: '',
    },
    methods: {
        showStatus(){
            this.showModal = true
            this.modalHeader = 'Confirmation'
            this.currentBody = 'StatusModal'

        },
        showUser(){
            this.showModal = true
            this.modalHeader = 'Confirmation'
            this.currentBody = 'UserModal'
        }
    }
})

Just for example here i have two modals ‘StatusModal’ and ‘UserModal’ and i load them in my js file, so if i have 13 or more modals i will load 13 components in my js file, i need a solution that load only component that i need when i call function, It’s possible to load component in function call?

I tried to use ajax and load blade content in ajax call and load it in my modal but i face a problem, i’m using vue validation for inputs so validation don’t work (vee-validate) also any vue variable does not compiled and i get {{ variable }} in my modal.

What is the best solution for my case? i appreciate any help

Advertisement

Answer

Edit after chat

Solution found:

HTML:

<component slot="body" :is="currentBody"></component>

JS:

showStatus() { 
  this.dialog = true 
  System.import('./components/modals/StatusModal.vue').then((response) => { 
    this.currentBody = response
  }); 
},

Previous answer

If using vue-cli webpack config(modules), I’d go for a solution as follow. The key point is using System.import. It’s the same thing as require but asynchronous. It will only resolve one time even if you call the same file multiple times. It’ll cache it client side.

I use a render function here, because it’s a lot easier to manage vue template replacement.

import Modal from './components/Modal.vue'

const profile = new Vue({
  render(h) {
    if (this.showModal) {
      return h('modal', {
        on: {
          close() {
            this.showModal = false
          }
        }
      }, [
        h('header', { slot: 'header' }, this.modalHeader),
        h(this.currentBody, { slot: 'body' })
      ]);
    } else {
      return null;
    }
  },
  data: {
    showModal: false,
    modalHeader: '',
    currentBody: {},
  },
  methods: {
    showStatus() {
      this.showModal = true
      this.modalHeader = 'Confirmation'
      this.currentBody = System.import('./components/modals/StatusModal.vue')
    },
    showUser() {
      this.showModal = true
      this.modalHeader = 'Confirmation'
      this.currentBody = System.import('./components/modals/UserModal.vue')
    }
  },
  components: {
    Modal
  }
})

Note I haven’t tested it. Let me know if anything goes wrong or if I misunderstood your case.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement