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.