-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow a user to read and write state on history entries (history.state) #2243
Comments
My app relies on being able to associate extra state in the history that isn't in the URL and this prevents me from being able to use
and provides access to location something like:
users aren't expected to access |
This would be extremely useful as a way to pass data to the scrollBehavior handler to allow different router-links that share the same |
To workaround this, I currently have to track changes to the $route globally, inspect and copy values from |
There are some scenarios where this is impossible to workaround. Our app has some popups that need to close on the device back press. Right now we add a query in the URL to do that but as the number of popups increases, our URLs would become nasty. The one and the only way to show a popup like a native app is to store its state in the history object. This way we can push the same URL and store a flag for the popup in the history so that on the device back it can be used to close the popup again. This not only solves the problem of closing a popup on the device back it will also persist the state on page refresh so that the popup can open up again without relying on the URL. There are cases where opening a popup with a URL change is the correct way but there are other cases too where a URL change is completely unnecessary. Take a look at this page. Open it in a mobile and click on view similar. They were able to do it because they used React. And we are not able to do it because of the default behaviour of vue-router. |
FYI since 3.1.4 you can overwrite the history state using |
Yeah, I can see that The only half ended solution that I can find is to use But still, the problem of persisting the popup state on page refresh will not get solved because the function
Maybe here if you could have written the logic of not replacing the state like this.
We could have implemented a full-fledged solution by now. |
Thank you so much for the quick fix. Hopefully in 3.2 we will be able to pass state objects in push/replace methods and get to from the route object maybe. |
As said, passing state through push/replace needs to go through the RFC process but right now you can just do await router.push('/somewhere')
history.replaceState({ ...history.state, ...newState }, '') To add state to the current history entry after a navigation |
I'd like to throw in my thoughts on this as you mentioned this is an RFC now. History state is a fantastic feature that would really improve vue router. I came across this issue when I ended up spending a few hours working on figuring out a way to get a workflow done without it. I was trying to figure out a way to easily and consistently make it so I could always return to the same page the user left from. (or the default if the user navigated directly to the <v-btn :to="{name: 'Other', state: {prevRoute: $route.fullPath}}">btn</v-btn> This would be paired with a corresponding button on the other page. That would've been all the code I needed to make the feature work the way I wanted and was the first thing I tried. <v-btn :to="$route.state?.prevRoute || '/overview/main' ">Return</v-btn> After finding this thread, I could've done the same awaiting programatic navigation and then a manual Instead I spent a couple hours searching through the api and trying things out ineffectively. Like the What I ended up with was setting up a beforeRouteEnter guard on the Which meant that I had to check to make sure that navigation to that route was coming from the What I ended up with was: beforeRouteEnter(to, from, next) {
next((vm) => {
if (from.name === 'Overview') {
vm.prevRoute = from.fullPath;
}
});
}, In react-router, the API already exists where you can just put a <Link to={{pathname: '/other', state: {prevRoute: location.pathname}}} /> I'm well aware that vue router and react router are very different in their philosophies, but I still feel like this should be standard in any history api based router due to both the convenience and the ability for state to be tied to a particular location in the browser history. The latter definitively adding a ton of possibilities that would otherwise require much less clean approaches. |
Published an RFC for this: vuejs/rfcs#400 |
Fixed in version 4.1!!! |
Just tried it in 4.1. We can now set |
Am I right in thinking there is no way to have state specified once and applied to all navigations? |
I hope this issue gets more traction because I am having quite a difficult time saving & restoring state |
I made a fork off of the Vue 2 router to solve this issue for me: https://github.com/ZachHaber/vue-router-state. It allows passing in |
Interesting, thanks for sharing. Maybe put the docs in the |
The docs on it are live and updated a little with the composables (from the vue-router 4 docs, as those still apply) as well as the history state parts. |
So I guess not really? As per the RFC:
Currently the e2e example sets up a |
What problem does this feature solve?
Mobile apps that want to save scroll position for elements besides window.
This would also allow the user to save whatever they want to history state. A project I'm working on now needs to keep track of what's "focused" per page and this seems like the correct place for it. It could also be a nice place for temporary form data. I'm sure there's a lot of use cases outside of this.
What does the proposed API look like?
I'm still thinking about it, though I think someone else thinking about it would be better. :)
I checked out
react-router
a bit and it looks like we can make state part of the Location object, so we can set it in$router.push|replace({...})
ornext({...})
calls. They use an additional argument but we might not need to?I took a quick look at react-router and it seems to allow for this: https://github.com/ReactTraining/react-router/blob/master/packages/react-router/docs/api/history.md
Also, this seems to talk directly to the situation we're facing with scrolling:
https://reacttraining.com/react-router/web/guides/scroll-restoration
Also some additional reading: https://github.com/ReactTraining/history#properties
Hopefully this is useful and doesn't seem like useless rambling.
The text was updated successfully, but these errors were encountered: