Programmatic Navigation of Vue Router Routes

John Au-Yeung - Jan 25 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at how to navigate through Vue Router routes dynamically.

Programmatic Navigation

We can navigate through routes programmatically in addition to using router-link to create a link to let users navigate through routes.

router.push(location, onComplete?, onAbort?)

To do this, we can use the $router instance available to a component to navigating routes programmatically.

router.push(…) is called when a router-link link is clicked. We can call it ourselves to programmatically navigate to routes.

For example, we can define routes and navigate through them programmatically as follows:

src/index.js :

const Foo = { template: "<p>foo</p>" };  
const Bar = { template: "<p>bar</p>" };

const routes = [  
  {  
    path: "/foo",  
    component: Foo  
  },  
  {  
    path: "/bar",  
    component: Bar  
  }  
];

const router = new VueRouter({  
  routes  
});

new Vue({  
  el: "#app",  
  router,  
  methods: {  
    goTo(route) {  
      this.$router.push(route);  
    }  
  }  
});
Enter fullscreen mode Exit fullscreen mode

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://unpkg.com/vue/dist/vue.js"></script>  
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      <div>  
        <a href="#" @click='goTo("foo")'>Foo</a>  
        <a href="#" @click='goTo("bar")'>Bar</a>  
      </div>  
      <router-view></router-view>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>
Enter fullscreen mode Exit fullscreen mode

In the code above, we have the goTo method that takes a string for the route that we want to go to.

In the method, we call this.$router.push(route); to go to the route we want to reach.

So when we click on Foo we see foo , and when we click on Bar we see bar .

We can also pass in an object as follows:

this.$router.push({ path: route });
Enter fullscreen mode Exit fullscreen mode

Also, we can go to named routes when $router.push . To do this, we write:

src/index.js :

const Foo = { template: "<p>foo</p>" };  
const Bar = { template: "<p>bar</p>" };

const routes = [  
  {  
    name: "foo",  
    path: "/foo",  
    component: Foo  
  },  
  {  
    name: "bar",  
    path: "/bar",  
    component: Bar  
  }  
];

const router = new VueRouter({  
  routes  
});

new Vue({  
  el: "#app",  
  router,  
  methods: {  
    goTo(name) {  
      this.$router.push({ name });  
    }  
  }  
});
Enter fullscreen mode Exit fullscreen mode

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://unpkg.com/vue/dist/vue.js"></script>  
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      <div>  
        <a href="#" @click='goTo("foo")'>Foo</a>  
        <a href="#" @click='goTo("bar")'>Bar</a>  
      </div>  
      <router-view></router-view>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>
Enter fullscreen mode Exit fullscreen mode

In the code above, we defined named routes by adding the name property to our routes by writing:

const routes = [  
  {  
    name: "foo",  
    path: "/foo",  
    component: Foo  
  },  
  {  
    name: "bar",  
    path: "/bar",  
    component: Bar  
  }  
];
Enter fullscreen mode Exit fullscreen mode

Then we can go to a route by name as follows in the goTo method:

this.$router.push({ name });
Enter fullscreen mode Exit fullscreen mode

We can pass in route parameters as follows:

router.push({ name: 'user', params: { userId: '123' } })
Enter fullscreen mode Exit fullscreen mode

The following won’t work:

router.push({ path: 'user', params: { userId: '123' } })
Enter fullscreen mode Exit fullscreen mode

We can go to routes with query strings as follows:

router.push({ path: 'user', query: { userId: '123' } })
Enter fullscreen mode Exit fullscreen mode

or:

router.push({ name: 'user', query: { userId: '123' } })
Enter fullscreen mode Exit fullscreen mode

We can also go on a path with a route parameter as follows:

router.push({ path: `/user/123` });
Enter fullscreen mode Exit fullscreen mode

For example, we can use them as follows:

const Foo = { template: "<p>foo {{$route.query.id}}</p>" };  
const Bar = { template: "<p>bar</p>" };

const routes = [  
  {  
    path: "/foo",  
    component: Foo  
  },  
  {  
    path: "/bar",  
    component: Bar  
  }  
];

const router = new VueRouter({  
  routes  
});

new Vue({  
  el: "#app",  
  router,  
  methods: {  
    goTo(path, query) {  
      this.$router.push({ path, query });  
    }  
  }  
});
Enter fullscreen mode Exit fullscreen mode

Then we see foo 1 when we click on Foo since we take a query string with id as the key.

It’s the same as going to /#/foo?id=1 in the browser.

The same rules apply for the to property of the router-link component.

In Vue Router 2.2.0 or later, we can optionally provide a onComplete and onAbort callbacks to router.push or router.replace as the 2nd and 3rd arguments.

In Vue Router 3.1.0+. router.push and router.replace will return promises and we don’t need to pass in the 2nd and 3rd arguments to handle those cases.

If our destination is the same as the current route and only the parameters are changing, like /users/1 to /users/2 , then we have to use beforeRouteUpdate hook to react to changes.

router.replace(location, onComplete?, onAbort?)

router.replace acts like router.push except that no new history entry is added.

router.replace(…) is the same as <router-link :to=”…” replace> .

router.go(n)

We can use router.go to go forward or backward by passing in an integer for the number of steps to go forward or back. Negative is backward and positive is forward.

For example, we can use it as follows:

src/index.js :

const Foo = { template: "<p>foo</p>" };  
const Bar = { template: "<p>bar</p>" };

const routes = [  
  {  
    path: "/foo",  
    component: Foo  
  },  
  {  
    path: "/bar",  
    component: Bar  
  }  
];

const router = new VueRouter({  
  routes  
});

new Vue({  
  el: "#app",  
  router,  
  methods: {  
    forward() {  
      this.$router.go(-1);  
    },  
    back() {  
      this.$router.go(1);  
    }  
  }  
});
Enter fullscreen mode Exit fullscreen mode

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://unpkg.com/vue/dist/vue.js"></script>  
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      <div>  
        <router-link to="foo">Foo</router-link>  
        <router-link to="bar">Bar</router-link>  
        <a href="#" @click="forward">Forward</a>  
        <a href="#" @click="back">Back</a>  
      </div>  
      <router-view></router-view>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>
Enter fullscreen mode Exit fullscreen mode

We have to forward and back methods to go forward and backward respectively.

router.go will fail silently if no such history record exists.

Conclusion

We have the router.push method to go to a path with different names, paths, query string or parameters.

Likewise, we can do the same with router.replace but without adding a new history entry.

They both take a string or object for the route and an onComplete and onAbort handlers.

router.go lets us go back and forward in the browser history. It takes a number of steps to go forward or back.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .