Search code examples
javascriptvue-routervue.js

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


I am trying to set query params with Vue-router when changing input fields, I don't want to navigate to some other page but just want to modify URL query params on the same page, I am doing this:

    this.$router.replace({ query: { q1: "q1" } })

But this also refreshes the page and sets the y position to 0, ie scrolls to the top of the page. Is this the correct way to set the URL query params or is there a better way to do it?


Edited:

Here is my router code:

    export default new Router({
      mode: 'history',
      scrollBehavior: (to, from, savedPosition)  => {
        if (to.hash) {
          return {selector: to.hash}
        } else {
          return {x: 0, y: 0}
        }
      },
      routes: [
        ....... 
        { path: '/user/:id', component: UserView },
      ]
    })

Solution

  • 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/guide/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. 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.