I'm using vue-router and i'm trying to create a functionality as follows:
I want to be able to specify in the router routes if a component should be rendered in modal or not. And if it is rendered in Modal keep every component below ( under modal-mask ) as it was.
I've created a modal-wrapper component that have basic modal structure and slot
inside its modal body so the component I want to render should go in the slot
. But how to achieve that. Does Vue-Router
have options for that functioanlity.
Router routes:
{
path: '/customers/:clientId',
component: customerView
meta: {
auth: true,
},
},
{
path: '/customers/:clientId/addAddress',
component: dataViewAdd
meta: {
openInModal: true,
auth: true,
},
},
Since if component should be rendered inside modal while overlaying the previous router-view, I guess ill need 2 router-views.
<router-view class="normal-view"></router-view>
<router-view class="modal-view" name="modal-view"></router-view>
If the component displayed in each modal route was not used in a non-modal context, then you can just modify the modal route component's template (dataViewAdd
) so that the modal component is the root of the template. But you mentioned that you would be reusing these components in different situations (so one route might use dataViewAdd
inside a modal and another route might use dataViewAdd
not inside a modal).
You could create wrapper modal versions of each component, but that'll become messy; it looks like you just want to be able to specify openInModal: true
and have it work for any component.
You also mentioned that the position of the modal in the DOM doesn't matter (otherwise I'd recommend using something like portal-vue
to assist with this).
First you'll need to change your router configuration so that the modal route is a child of the component you want to keep visible underneath it. Make sure customerView
has a <router-view>
inside it.
Create a helper function which returns a modal-wrapped version of the component and use that as the route component. This doesn't use the openInModal
meta property, but it works in a similar way.
The following code is untested.
import Modal from './modal.vue';
function wrapInsideModal(childComponent) {
return {
functional: true,
render(h) {
return h(Modal, [h(childComponent)]);
},
};
}
// Routes
{
path: '/customers/:clientId',
component: customerView,
meta: {
auth: true,
},
children: [
{
path: 'addAddress',
component: wrapInsideModal(dataViewAdd),
},
],
},
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With