Categories
JavaScript Vue

Changing Scroll Behavior with Vue Router

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

Vue Router is a URL router that maps URLs to components.

In this article, we’ll look at how to change the scroll behavior of Vue Router routes.

Changing Scroll Behavior

Sometimes we may want to scroll to top when navigating to a new route or preserve the scrolling position of history entities like a real page reload.

Vue Router lets us adjust the scrolling behavior the way we like when route loads.

This only works if the browser supports history.pushState .

We can adjust scrolling behavior by providing a scrollBehavior function.

It has a to and from route objects as the first 2 parameters. The third argument is savePosition , is only available if this is a popstate navigation triggered by the browser’s back or forward buttons.

The function can return a scroll position object in the form of:

{ x: number, y: number }

or:

{ selector: string, offset? : { x: number, y: number }}

offset is supported since Vue Router 2.6.0

For example, we can add scrollBehavior to our routes as follows:

src/index.js:

const Foo = {  
  template: `  
    <div>  
      <div v-for='n in 100'>{{n}} foo</div>  
    </div>  
  `  
};  
const Bar = {  
  template: `  
  <div>  
    <div v-for='n in 100'>{{n}} bar</div>  
  </div>  
  `  
};

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

const router = new VueRouter({  
  routes,  
  scrollBehavior(to, from, savedPosition) {  
    return { x: 0, y: 0 };  
  }  
});new Vue({  
  el: "#app",  
  router  
});

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">  
      <router-view></router-view>  
      <router-link to="foo">Foo</router-link>  
      <router-link to="bar">Bar</router-link>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

In the code above, we have:

scrollBehavior(to, from, savedPosition) {  
  return { x: 0, y: 0 };  
}

to scroll the next page back to the top when we navigate. Therefore, when we click on the links at the bottom of the page, we’ll go back to the top.

If we return something falsy or an empty object, no scrolling will happen.

If we change scrollBehavior to:

scrollBehavior(to, from, savedPosition) {  
  if (savedPosition) {  
    return savedPosition;  
  } else {  
    return { x: 0, y: 0 };  
  }  
}

Then we keep the scroll position of the page when we navigate back and forth with the forward and back buttons.

We can create the scroll to anchor behavior by setting the ID on our elements and then changing scrollBehavior as follows:

src/index.js :

const Foo = {  
  template: `  
    <div>  
      <div v-for='n in 100' :id='n'>{{n}} foo</div>  
    </div>  
  `  
};

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

const router = new VueRouter({  
  routes,  
  scrollBehavior(to, from, savedPosition) {  
    if (to.hash) {  
      return {  
        selector: to.hash  
      };  
    }  
  }  
});

new Vue({  
  el: "#app",  
  router  
});

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">  
      <router-view></router-view>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then when we go to /#/foo#100 we scroll to the bottom, then when we go to /#/foo#20 , we see 20 foo at the top of the screen.

Async Scrolling

We can also to async scrolling with scrollBehavior since Vue Router 2.8.0 by returning a promise that resolves to the same objects as synchronous scrolling.

For example, we can change the example above to:

src/index.js :

const Foo = {  
  template: `  
    <div>  
      <div v-for='n in 100' :id='n'>{{n}} foo</div>  
    </div>  
  `  
};

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

const router = new VueRouter({  
  routes,  
  scrollBehavior(to, from, savedPosition) {  
    if (to.hash) {  
      return new Promise((resolve, reject) => {  
        setTimeout(() => {  
          resolve({  
            selector: to.hash  
          });  
        }, 1000);  
      });  
    }  
  }  
});

new Vue({  
  el: "#app",  
  router  
});

Then when we go to /#/foo#100 in our browser, we scroll to the bottom of the page after a second.

Conclusion

Scrolling behavior during route navigation can be changed by adding a scrollBehavior function to our router object. It takes the to and from parameters which are route objects, and a 3rd savedPosition parameter with the saved scroll position of the navigated route.

Scrolling behavior can be synchronous or asynchronous since Vue Router 2.8.0.

We can scroll to an element with the CSS selector or position.

Categories
Vue

Dynamic Route Matching with Vue Router

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 match routes dynamically with Vue Router.

Route Parameters

We can get route parameters with the this.$route.params object.

For example, we can write an app that shows the URL parameter that’s passed in as follows:

src/index.js :

const User = {
  computed: {
    username() {
      return this.$route.params.username;
    }
  },
  template: `<div>{{username}}</div>`
};

const routes = [{ path: "/user/:username", component: User }];

const router = new VueRouter({
  routes
});

new Vue({
  el: "#app",
  router
});

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="/user/foo">Foo</router-link>
        <router-link to="/user/bar">Bar</router-link>
      </div>
      <router-view></router-view>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>

The :username in “/user/:username” is the parameter, so we can get what passed in after /user/ by using this.$route.params.username .

We added a computed property username which returns this.$route.params.username so we can use:

`<div>{{username}}</div>`

to show the username URL parameter.

We can also have multiple parameters in one route.

For example, we can write the following:

src/index.js :

const Name = {
  template: `<div>
    {{$route.params.firstName}}
    {{$route.params.lastName}}
  </div>`
};

const routes = [{ path: "/name/:firstName/:lastName", component: Name }];

const router = new VueRouter({
  routes
});

new Vue({
  el: "#app",
  router
});

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="/name/Jane/Doe">Jane</router-link>
        <router-link to="/name/Mary/Smith">Mary</router-link>
      </div>
      <router-view></router-view>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>

Then when we click on the links, we get the first name and last name that we passed into the URL parameters.

:firstName and :lastName are matched to the params by position.

Reacting to Params Changes

We can watch the $route object to watch for param changes. Routes that the same name but different params use the same components. They won’t be re-rendered from scratch, so the lifecycle hooks won’t be called.

For example, we can write the following:

src/index.js :

const Name = {
  data() {
    return {
      oldName: "",
      newName: ""
    };
  },
  watch: {
    $route(to, from) {
      this.oldName = from.params.name;
      this.newName = to.params.name;
    }
  },
  template: `<div>
    Old: {{oldName}}
    New: {{newName}}
  </div>`
};

const routes = [{ path: "/name/:name", component: Name }];

const router = new VueRouter({
  routes
});

new Vue({
  el: "#app",
  router
});

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="/name/Jane">Jane</router-link>
        <router-link to="/name/Mary">Mary</router-link>
      </div>
      <router-view></router-view>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>

In the code above, we have the Name component that’s mapped to a route that takes the name route parameter.

Also, Name has watcher for the $route object that takes the to and from parameters. They are the previous and current routes respectively.

So when we click back and forth between links, we’ll see the old parameter and new parameter displayed.

Catch all / 404 Not found Route

We can add * as a wildcard character for routes.

For example, we can use:

path: '*'

to match all routes and:

path: '/user-*'

to match anything that begins with user- .

For example, we can use the wildcard character as follows:

src/index.js :

const Foo = { template: "<p>foo</p>" };
const Bar = { template: "<p>bar</p>" };
const NotFound = { template: "<p>not found</p>" };
const routes = [
  { path: "/foo", component: Foo },
  { path: "/bar", component: Bar },
  { path: "*", component: NotFound }
];

const router = new VueRouter({
  routes
});

new Vue({
  el: "#app",
  router
});

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>
      </div>
      <router-view></router-view>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>

When we go to any URL other than /foo or /bar , we’ll see the ‘not found’ message.

We can use the wildcard character with other text 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
});

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>
      </div>
      <router-view></router-view>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>

Then we see foo when we go to any URL that starts with foo .

Regular Expressions

We can use regular expressions to match route parameters. For example, we can write:

src/index.js :

const Foo = { template: "<p>foo {{$route.params.id}}</p>" };
const Bar = { template: "<p>bar</p>" };
const routes = [
  { path: "/foo/:id(d+)", component: Foo },
  { path: "/bar", component: Bar }
];

const router = new VueRouter({
  routes
});

new Vue({
  el: "#app",
  router
});

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>
      </div>
      <router-view></router-view>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>

Then when we go to /foo/1 we see foo 1 . If what comes after /foo/ isn’t a number, then we won’t see anything.

Conclusion

We can pass in route parameters by prefix whatever we want to pass in with a colon, then we can get it from the this.$route.params object.

The asterisk is a wildcard character that matches any URLs that don’t match the routes listed. We can also combine it with other text to match patterns that we want to match.

Finally, we can use regex to match route parameters.

Categories
JavaScript Vue

Programmatic Navigation of Vue Router Routes

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);  
    }  
  }  
});

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>

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 });

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 });  
    }  
  }  
});

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>

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  
  }  
];

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

this.$router.push({ name });

We can pass in route parameters as follows:

router.push({ name: 'user', params: { userId: '123' } })

The following won’t work:

router.push({ path: 'user', params: { userId: '123' } })

We can go to routes with query strings as follows:

router.push({ path: 'user', query: { userId: '123' } })

or:

router.push({ name: 'user', query: { userId: '123' } })

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

router.push({ path: `/user/123` });

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 });  
    }  
  }  
});

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);  
    }  
  }  
});

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>

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.

Categories
JavaScript Vue

Programmatic Navigation of Vue Router Routes

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);  
    }  
  }  
});

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>

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 });

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 });  
    }  
  }  
});

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>

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  
  }  
];

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

this.$router.push({ name });

We can pass in route parameters as follows:

router.push({ name: 'user', params: { userId: '123' } })

The following won’t work:

router.push({ path: 'user', params: { userId: '123' } })

We can go to routes with query strings as follows:

router.push({ path: 'user', query: { userId: '123' } })

or:

router.push({ name: 'user', query: { userId: '123' } })

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

router.push({ path: `/user/123` });

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 });  
    }  
  }  
});

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);  
    }  
  }  
});

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>

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.

Categories
JavaScript Vue

Redirect and Alias with Vue Router

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

Vue Router is a URL router that maps URLs to components.

In this article, we’ll look at how to add redirects and alias to our routes.

Redirect

We can add redirects from one route to another by adding the redirect property to a route.

For example, we can add a redirect as follows:

src/index.js :

const Bar = { template: "<div>bar</div>" };  
const routes = [  
  { path: "/foo", redirect: "/bar" },  
  { path: "/bar", component: Bar }  
];

const router = new VueRouter({  
  routes  
});

new Vue({  
  el: "#app",  
  router  
});

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="[https://unpkg.com/vue/dist/vue.js](https://unpkg.com/vue/dist/vue.js)"></script>  
    <script src="[https://unpkg.com/vue-router/dist/vue-router.js](https://unpkg.com/vue-router/dist/vue-router.js)"></script>  
  </head>  
  <body>  
    <div id="app">  
      <router-view></router-view>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then when we go to /#/bar in the browser, we get bar displayed.

A redirect can also target a named route. For example, we can write:

src/index.js :

const Bar = { template: "<div>bar</div>" };  
const routes = [  
  { path: "/foo", redirect: { name: "bar" } },  
  { path: "/bar", component: Bar, name: "bar" }  
];

const router = new VueRouter({  
  routes  
});

new Vue({  
  el: "#app",  
  router  
});

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">  
      <router-view></router-view>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then we get the same result.

We can also set the redirect property to a function. For instance, we can set it to a function that returns a route as follows:

src/index.js :

const Bar = { template: "<div>bar</div>" };  
const routes = [  
  { path: "/foo", redirect: to => "bar" },  
  { path: "/bar", component: Bar }  
];

const router = new VueRouter({  
  routes  
});

new Vue({  
  el: "#app",  
  router  
});

Then we get the same result as the previous examples.

Navigation guards aren’t applied on routes that redirect, only on its target. Alias

A redirect means that when a user visits /foo then the URL will be replaced by /bar and then matched as /bar .

An alias means of /foo that’s set as /bar means that when the user visits /bar , the URL remains /bar , but it’ll be matched as if the user is visiting /foo .

For example, we can define a route with an alias as follows:

src/index.js :

const Foo = { template: "<div>foo</div>" };  
const routes = [{ path: "/foo", component: Foo, alias: "/bar" }];

const router = new VueRouter({  
  routes  
});

new Vue({  
  el: "#app",  
  router  
});

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">  
      <router-view></router-view>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then we get foo when we go to /#/foo or /#/bar .

An alias lets us map any route to any URL without being constrained by the nesting structure of the routes.

This is handy for mapping a URL that we want for a nested route.

For example, if we define an alias for a nested route as follows:

src/index.js :

const Foo = {  
  template: `<div>  
    foo  
    <router-view></router-view>  
  </div>`  
};  
const Bar = { template: "<div>bar</div>" };  
const routes = [  
  {  
    path: "/foo",  
    component: Foo,  
    children: [{ path: "/bar", component: Bar }]  
  }  
];

const router = new VueRouter({  
  routes  
});

new Vue({  
  el: "#app",  
  router  
});

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">  
      <router-view></router-view>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then when we go to /#/foobar , we get:

foobar

displayed on the screen.

We also get the same thing displayed if we go to /#/foo/bar .

Therefore, we don’t have to follow the usual convention for nested route URLs if we use an alias.

Conclusion

Redirects and aliases are handy features of the Vue Router.

Redirects let us redirect from one route to another. Navigation guards aren’t run on redirect routes.

Aliases let us create a new URL for an existing route. When we go to the path or the alias, we get the same result when we map a path to an alias.

This is handy when we don’t want to follow the usual convention for nested route URLs for example.