Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set URL query params in Vue with Vue-Router

People also ask

How do I pass a query parameter in vue?

In the <route-link> component, we can set the query params to a URL using :to prop. If you want to set a query params dynamically to a URL, you can use this. $router. push() method.

How do I push parameters on my router?

To pass parameters using router. push() , you can do one of the following: router. push({ name: 'user', params: {id: 123}}); // or const id = 123; router.

How do I get parameters on route vue?

to get the value of the id route parameter with this. $route.params.id with the options API. We call useRoute to return the route object and then we get the value of the id route parameter with route.params.id .

How can I get query parameters from a URL in vue js?

If we don't use Vue Router, then we can get the query parameter with the URLSearchParams constructor. We call the URLSearchParams constructor with window. location.search , which has the query string. Then we can get the query parameter with the given key with urlParams.


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 view
  • name or path 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.


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.


Actually you can just push query like this: this.$router.push({query: {plan: 'private'}})

Based on: https://github.com/vuejs/vue-router/issues/1631


If you are trying to keep some parameters, while changing others, be sure to copy the state of the vue router query and not reuse it.

This works, since you are making an unreferenced copy:

  const query = Object.assign({}, this.$route.query);
  query.page = page;
  query.limit = rowsPerPage;
  await this.$router.push({ query });

while below will lead to Vue Router thinking you are reusing the same query and lead to the NavigationDuplicated error:

  const query = this.$route.query;
  query.page = page;
  query.limit = rowsPerPage;
  await this.$router.push({ query });

Of course, you could decompose the query object, such as follows, but you'll need to be aware of all the query parameters to your page, otherwise you risk losing them in the resultant navigation.

  const { page, limit, ...otherParams } = this.$route.query;
  await this.$router.push(Object.assign({
    page: page,
    limit: rowsPerPage
  }, otherParams));
);

Note, while the above example is for push(), this works with replace() too.

Tested with vue-router 3.1.6.