I am working in the project developed with Vue 2 with VueRouter and I am trying to work with my modals controlled by my VueRouter!
I've done the following code
Main vue component: My normal components will be loaded on the default router-view and all my modals will be loaded on the modal router-view
<div id="app">
<router-view v-if="!isLoading"></router-view>
<router-view v-if="!isLoading" name="modal"></router-view>
</div>
RoutedModals Mixing As you can see on my beforeRouteEnter method I am checking if there is a previous "from" route (which means the user got the page navigating inside the app)... If it's I set that one as default component... if not (which means the user got directly from the URL) I set my dashboard as default and it will be opened behind my modal.
import Dashboard from 'modules/dashboard/components/Main.vue'
import { isNil } from 'lodash'
export default {
data() {
return {
canAccessDirect: true,
goBackTo: '/'
}
},
beforeRouteEnter(to, from, next) {
to.matched[0].components.default = isNil(from.matched[0]) ? Dashboard : from.matched[0].components.default
next(vm => {
if (!vm.canAccessDirect)
vm.$router.push({
name: 'dashboard.index'
})
vm.fetchRecords()
vm.goBackTo = from.path
window.jQuery(vm.$el).modal('show')
window.jQuery(vm.$el).on('hide.bs.modal', () => {
vm.$router.push(vm.goBackTo)
})
})
},
beforeRouteLeave(to, from, next) {
setTimeout(() => {
next()
}, 200)
},
methods: {
fetchRecords() {
// Do list request
}
}
}
An example of my router object: The first route will open a modal on the router-view modal and the second will open only on the default router-view
{
name: 'leads.quick-add',
path: '/leads/quick-add',
components: { modal: QuickAdd },
},
{
name: 'leads.index',
path: '/leads',
component: Main,
},
It works great! The problem comes when I access my modal URL (does not matter if it's directly or navigating) and the default component has a child component! The child component get away on that case!
There is attached some screenshots to help you out understand what happens...
At Image 1 we can 2 components where the number 1 is my default component on my VueRouter and the number 2 is his child!
Ar the Image 2, after clicking on the + Quotation button the modal is loaded and the component number 2 getaway!
Any ideas on how to do it keeping the others components?
Just to be clear I want to do it by routing and no calling my modal manually!
########################## Edit I am trying to do something like that instead of check on beforeRouterEnter method:
{
name: 'leads.show.quotations.create',
path: '/leads/:id/quotations/create',
components: {
default: Show,
'default.tab': Quotations,
modal: Add
},
meta: {
requiresAuth: true
}
},
Where there is a sub-router-view but it does not work!
Thinking about possibilities I've added this issue on the github repo: https://github.com/vuejs/vue-router/issues/1030
I did this in a project at work. It is quite simple actually, the hard part lies in mixing the jquery that you have there, and maybe the css to position a modal, since it's entry point is the router-view inside your component I recommend using the package portal-vue to move the modal content to the end of the body.
Here is a working exemple: https://codesandbox.io/s/vue-router-modal-j10t2
First create a Modal Component that receives it's child by props:
Then you can use the props in routes to assign the content for a given route:
Since the modal is a child route of '/', the Home component needs to render the router-view:
And the App.vue needs to render the portal target, so the modal goes to the end of your content (it makes positioning the modal a lot easier):
And that's it