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.