Reputation: 386
I'm working with Vue 2 and I have some issues with the history when navigating back.
I have the following:
/page-1/{id}
|
v
/page-1/{id}/overview
|
v
user clicks on edit
|
v
/page-1/{id}/overview/edit
|
v
user navigate pages, example /page-1/{id}/details/edit
|
v
user confirms changes
|
v
/page-1/{id}
When the user confirm the changes it will be redirected back to /page-1/{id}
. However, if the user then clicks the back button it will be redirected to /page-1/{id}/details/edit
, which is the previous route. Instead I would like to be able to go back to the route that was visited before entering the edit mode: /page-1/{id}/overview
.
/page-1/{id}
|
v
/page-1/{id}/overview <-------------------------------------+
| |
v |
user clicks on edit |
| |
v |
/page-1/{id}/overview/edit <-----------------------------+ |
| | | |
| v | |
| user navigate pages, ex: /page-1/{id}/details/edit | |
| | | |
| v | |
| back button -----------------------------------------+ |
V |
user confirms changes |
| |
v |
/page-1/{id} |
| |
v |
back button -------------------------------------------+
It looks like I have to erase the "edit" history when the changes are confirmed. Is there a way to do this in vue? Or kind of create a separate history for the edit pages...
Thank you
UPDATE
I found an npm package that looks like is doing what Im looking for
https://www.npmjs.com/package/vue-router-back-button
However, looks like I need to hard reload the page at each page visit to make it work....
UPDATE
Ok, found a solution, I keep different Histories depending on in which state Im in:
When we move out from the edit state, the edit history is erased and we return to the regular history. This can be further improved with sub hisotries if needed.
/page-1/{id} -> /page-1/{id}/overview History[
/page-1/{id},
/page-1/{id}/overview
]
/page-1/{id}/overview -> /page-1/{id}/overview/edit EditHistory[
/page-1/{id}/overview/edit
] (switch to edit history)
/page-1/{id}/overview/edit -> /page-1/{id}/details/edit EditHistory[
/page-1/{id}/overview,
/page-1/{id}/overview/edit, /page-1/{id}/details/edit
]
/page-1/{id}/overview/edit <- /page-1/{id}/details/edit EditHistory[
/page-1/{id}/overview/edit
]
User save EditHistory[
] (switch to history)
/page-1/{id}/overview/ User is now at the most recent entry in the history
If the user saved in the /page-1/{id}/overview/details/edit page, then the edit history is erased and the url /page-1/{id}/overview/details/ will be pushed in the History:
History[
/page-1/{id},
/page-1/{id}/overview,
/page-1/{id}/details,
]
If now the user clicks back it will be sent back to the overview :)
Btw, seems to work nice, but for some reason, sometimes the popState event is not catched by the listener (probably not even thrown by the browser?) This results in having to click back twice. Are there situation where the popstate event is not raised even if the user clicks the back button?
Upvotes: 1
Views: 4190
Reputation: 31
If you want you can avoid this issue, instead of using router.push
(which is default for vue router), you can use router.replace
, which will replace current URL in history mode with new one. Really useful for blocking user from re-entering the page you don't want them to enter again via history.
Use router.replace('<wanted-route>')
instead of router.push('<wanted-route>')
How it would be applicable in your case (thank you for the quick route diagram, really useful for explanations):
router.push(`/page-1/${id}`)
|
v
router.push(`/page-1/${id}/overview`) <--------------------+
| |
v |
user clicks on edit |
| |
v |
router.push(`/page-1/${id}/overview/edit`) <--------------+ |
| | | |
| v | |
| user navigate pages, ex: /page-1/{id}/details/edit | |
| | | |
| v | |
| back button -----------------------------------------+ |
V |
user confirms changes |
| |
v |
router.replace(`/page-1/${id}`) |
| |
v |
back button -------------------------------------------+
This will replace last history object with new path object. Example of history objects by URL-s.
Original:
/page-1/{id} -> /page-1/{id}/overview -> /page-1/{id}/overview/edit -> /page-1/{id}
Router replace:
/page-1/{id} -> /page-1/{id}/overview -> /page-1/{id}
More info: https://router.vuejs.org/guide/essentials/navigation.html#replace-current-location
Upvotes: 1