DEV Community

Discussion on: Handling Dialogs with Vue Router

Collapse
 
kevnk profile image
Kevin Kirchner

Thanks for this. This is helpful.

One question: What if I wanted multiple dialogs to pop-up on any/all pages? How would you DRY up your routes.js?

Collapse
 
berniwittmann profile image
Bernhard Wittmann

I think this approach of using vue router couples the logic of the modals Reiniger to the url/page structure. E.g. A User Edit Modal will always be rendered only on the User Page (since the reference is strongly connected via the routes.js declaration)

I guess you want a more flexible approach (like displaying any modal on any page). This can be done with vuex (you would move the logic of which dialogs should be displayed to vuex) and then somewhere in your app (probably the root component) you could do something like this

<template>
    <dialog-1 v-if="dialog1visible"/>
    <dialog-2 v-if="dialog2Visible"/>

    // the App itself or your root router-view
    <router-view/>
</template>

You can of course combine both approaches and tailor it to your needs

If you want to get a little more info, I'd be glad to elaborate on this :)

Collapse
 
stepanorda profile image
Stepan

Hey I have a similar but even more complicated case. I want to build a gallery that works like dribbble.com/ . You have different routes with different galleries/filters/sorting represented in the route and then when you open a work URL changes to direct link to work (so it could be shared and it's a unique link for SEO purposes). Something like /work/{id}. But everything under modal stays the same saving the context for the user. For now I made it with nested views and PREVIOUS_ROUTE/work/{id} is added at the end. But that's not ideal for SEO (there are many links to the same work) and usability (what if user shares this link and then the work disappears from the gallery it was before or goes to 107 page in that gallery). The only idea I have now is to just handle it myself programatically with wildcard route and writing the whole logic myself.

Thread Thread
 
berniwittmann profile image
Bernhard Wittmann

I think the problem you're having is that you are loosing the filter/sorting information.
Your gallery retrieves this information from the url (like /gallery/illustrations?filter=today&sort=best, yet when a single work is displayed you want to remove this information in the url (/work/1231314). How should the page know what gallery to display below...

I have the following idea to solve this problem:
We need to store the filter sorting information for the gallery somewhere. What if the sorting/filter information of the url is stored somewhere in the localStorage, when you visit a gallery page and updated accordingly. Then the information is safely stored in the local storage, but it can still be controlled via the url.
When the user now navigates to a work url, the component responsible for rendering the gallery can load the sorting information from localstorage and still render gallery from before.

Yet this approach has the caveat, that you have to handle, when no gallery information is present (could be the case when a user goes to a work url, without having visited any gallery before). But this could be solved with some appropriate defaults like showing some default gallery.

Also this approach for information storage should allow you to apply the idea of the dialog of this article again more easily and you are able to separate the work logic from the gallery logic, since you can just reuse the gallery component.

I hope I could express my idea adequately, and if you have more questions just let me know and i will try to express my idea an another way or maybe provide some code snippets to make it more clear :)
And please let me know, whether it works out ;)

Thread Thread
 
stepanorda profile image
Stepan

Well how to store the data is not the problem, I get that. I'm using vuex all the way. Question is how to "trick" vue-router so it will not destroy the underlying layer with gallery when the path changes. Maybe there are a better way then just writing huge component that would handle everything manually and making it a "*" route.

Thread Thread
 
berniwittmann profile image
Bernhard Wittmann

The thing is you don't have to worry about destroying the underlying gallery since the gallery does not depend on the route itself anymore (only indirectly).

I just adjusted the example code to showcase that this can indeed work. Just see this branch: github.com/BerniWittmann/vue-route...

You can navigate to localhost:8080/nested/one?foo=test which resembles the gallery and see the query parameters rendered (because they have been stored in the state in the beforeEnter route guard). When you click on the show dialog button the url changes to /dialog which resembles the work page. You will see, that the page below did not change. It still has the query parameters rendered and also it was not even rerendered at all, which you can see at the timestamp.
As you'll see the back/close button will also work as expected and you can easily specify a default behavior when the local storage is empty on the work page. Hope that helps ;)

Thread Thread
 
stepanorda profile image
Stepan

Thank you, now I get your idea :) Really appreciate your going to such a length trying to help me!

Thread Thread
 
berniwittmann profile image
Bernhard Wittmann

No worries, Iβ€˜m glad to help :)

Thread Thread
 
stepanorda profile image
Stepan

For everybody who would like me google and find your article first:
github.com/vuejs/vue-router/issues...
This is a known issue, there are future request in and it's planned to be addressed by vue-router.
There are also a lot of hacky solutions for this in that issue.

Collapse
 
kevnk profile image
Kevin Kirchner

Thanks. Vuex is a good alternative.

I started implementing your first proposal and discovered what you mentioned about specific dialogs only being needed in one place.

One gotcha I got stuck on for a bit was I had children of children routes and didn't realize that each one needed a router-view to render their children.

Thanks again

Thread Thread
 
berniwittmann profile image
Bernhard Wittmann

Yes thatβ€˜s due to the architecture of cue router

Youβ€˜re welcome