How to set URL query params in Vue with Vue-Router
Without reloading the page or refreshing the dom, history.pushState
can do the job.
Add this method in your component or elsewhere to do that:
addParamsToLocation(params) {
history.pushState(
{},
null,
this.$route.path +
'?' +
Object.keys(params)
.map(key => {
return (
encodeURIComponent(key) + '=' + encodeURIComponent(params[key])
)
})
.join('&')
)
}
So anywhere in your component, call addParamsToLocation({foo: 'bar'})
to push the current location with query params in the window.history stack.
To add query params to current location without pushing a new history entry, use history.replaceState
instead.
Tested with Vue 2.6.10 and Nuxt 2.8.1.
Be careful with this method!
Vue Router don't know that url has changed, so it doesn't reflect url after pushState.
Here is the example in docs:
// with query, resulting in /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
Ref: https://router.vuejs.org/en/essentials/navigation.html
As mentioned in those docs, router.replace
works like router.push
So, you seem to have it right in your sample code in question. But I think you may need to include either name
or path
parameter also, so that the router has some route to navigate to. Without a name
or path
, it does not look very meaningful.
This is my current understanding now:
query
is optional for router - some additional info for the component to construct the viewname
orpath
is mandatory - it decides what component to show in your<router-view>
.
That might be the missing thing in your sample code.
EDIT: Additional details after comments
Have you tried using named routes in this case? You have dynamic routes, and it is easier to provide params and query separately:
routes: [
{ name: 'user-view', path: '/user/:id', component: UserView },
// other routes
]
and then in your methods:
this.$router.replace({ name: "user-view", params: {id:"123"}, query: {q1: "q1"} })
Technically there is no difference between the above and this.$router.replace({path: "/user/123", query:{q1: "q1"}})
, but it is easier to supply dynamic params on named routes than composing the route string. But in either cases, query params should be taken into account. In either case, I couldn't find anything wrong with the way query params are handled.
After you are inside the route, you can fetch your dynamic params as this.$route.params.id
and your query params as this.$route.query.q1
.