Vue Router requests are persisted at the parent component level
I have an application in which the component Foo
is used as a template for the route app/foo
. This component has child components that are also used as templates for routes : app/foo/bar
, app/foo/baz
etc.
I bind a global storage object vuex
to a query
route property so that if the object is given, say { a: 1, b: 2 }
, the URL parameters will change to ?a=1&b=2
; and if the user changes the parameters, say the ?a=0&b=0
object will be updated to { a: 0, b: 0 }
. This all works as expected.
The problem I am facing is that when I head to any path under app/foo
, I lose the route property query
and the url parameters disappear.
I can pass the object query
dynamically like this:
this.$router.push({ name: 'bar', query: this.$route.query });
But it quickly becomes difficult to maintain.
I know Vue Router provides added lifecycle events and I thought I should update the request for the Foo
component beforeRouteUpdate
. I have made several different attempts, but not a cube:
beforeRouteUpdate (to, from, next) {
// This gives me an error saying that the query is read-only
to.query = from.query;
// This does not update the query
this.$router.replace({ query: from.query })
next();
},
Edit:
I also tried setting the observer to $route
to replace the request when the route changes. However, this causes an infinite loop:
watch: {
$route(to, from) {
this.$router.replace({ query: from.query });
}
}
Does anyone know how to make the Vue Router request persistent at the component level?
source to share
Based on @craig_h's comment, I added an observer to $route
:
watch: {
$route(to, from) {
if (to.path != from.path) { // to prevent an infinite loop
this.$router.replace({ query: from.query })
}
}
}
This will work in most cases, except when a component is accidentally routed to the current route. In this case, the request is still lost because the values to.path
and are the from.path
same.
My workaround for this is to add checks to those components that could route the current route:
if ((name != this.$route.name) || (params != this.$route.params)) {
this.$router.push({ name, params });
}
It works, but still not perfect.
source to share