In the first part of this little series on Vue Router Architecture I wrote about handling nested routes with Vue Router. It would maybe easier to f...
For further actions, you may consider blocking this person and/or reporting abuse
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?
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
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 :)
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
Yes that‘s due to the architecture of cue router
You‘re welcome
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.
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 ;)
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.
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 ;)
Thank you, now I get your idea :) Really appreciate your going to such a length trying to help me!
No worries, I‘m glad to help :)
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.
This was very mind oppenning, thanks ;-)
BTW
Since dialog is expected to be on top, code would be more semantinc if you put router-view named dialog at the end in template.
Yes you're right, that this would be better semantically. However, since you need to apply some css to make it look like a dialog it's not that big of a deal
Agree ;-)
Thank for the article, this is what I was looking for !
Just a question, I tried to implement in my projet:
I have in my nested page a long list of articles (coming from my store fetched at "created"). When I scroll and click to an article to display the dialog, I'm losing my scroll position at my selected article.
Do you have some tricks to keep the scroll position of the child component in the background of the dialog ?
You can control the scrolling behavior with vue router. Take a look at the docs
This approach is clean, however it doesn't look like it supports providing a custom action for the dialog, especially if the function resides in the sibling component of the dialog.
I‘m sorry, but I seem to not understand what you mean by custom action and by the function you mentioned. Maybe you could explain a little more about what you would like to achieve/mean?
What I meant by custom action is when you implement a confirm or cancel action to the dialog aside from closing it. I can't figure out yet how to provide a function from MyPageView to MyDialogComponent without using vuex.
Ah I see. The whole idea of this approach is not to create a single MyDialogComponent that can be used in several locations, but to create several dialogs for different purposes. This ties the dialogs closer to the business logic if you will.
However you can control sone behavior via url parameters or some query string in the url.
Let’s use an example:
The goal is to create a dialog that pops up for confirmation after editing a form. This form can either trigger a create or an update request.
Therefore the dialog should display some text and a button Text depending on the action type. The confirm button will then either trigger a create or an update request.
The approach outlined in the article would propose two separate dialogs living in their own vue router routes eg /confirm/edit and /confirm/create (You can still avoid code duplication by using components)
You could still use one dialog, that would render content or do stuff conditionally depending on the url, but that would probably violate the single purpose idea
Let me know whether this could clarify things. If not I can also put together a code snippet. Just let me know
This made much more sense in relation to the business logic.
I'm actually using this approach for a reusable notification/error dialog, which, upon reading your reply, seems like not the best use case for this pattern. I may not use it right now, but I will definitely adapt this where it's appropriate. Thank you for taking the time to respond
Yes, in that case some more reusable dialog would probably by the way to go :)
Of course, such discussions are the key for this dev community and I'm glad to help