Adding Meta Fields and Transitions to Vue Router Routes
Tags: webdev, programming, javascript, vue
Published: 2021-01-25 23:22:06

**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.

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

In this article, we’ll look at how to add meta fields and transition effects to routes.

Adding Meta Fields to Routes
============================

We can add meta fields to routes so that they can be checked in navigation guards and components.

For example, we can add a `meta` field indicating which fields need authentication and then check if an auth token is stored in local storage as follows:

`src/index.js` :

```
const Login = {  
  template: "<div>login</div>"  
};  
const Profile = {  
  template: "<div>profile</div>"  
};  
const routes = [  
  {  
    path: "/",  
    component: Login  
  },  
  {  
    path: "/profile",  
    component: Profile,  
    meta: { requireAuth: true }  
  }  
];

const router = new VueRouter({  
  routes  
});

router.beforeEach((to, from, next) => {  
  if (to.meta.requireAuth) {  
    if (!localStorage.getItem("token")) {  
      next("/");  
    } else {  
      next();  
    }  
  } else {  
    next();  
  }  
});

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>
```

The code above has a global `beforeEach` guard to check if `meta` field with `requiredAuth` set to `true` .

Then if it is, we’ll check if `localStorage.token` exists, and then complete navigation if it’s present.

Otherwise, we cancel navigation of the current route and navigate to `/` .

In all other cases, we continue with the navigation.

Accessing Route Meta Field within Components
============================================

We can access the `meta` field in components using the `$route.meta` field.

For example, we can write the following to get the `id` meta field displayed in our template:

`src/index.js` :

```
const User = {  
  template: "<div>user {{$route.meta.id}}</div>"  
};

const routes = [  
  {  
    path: "/",  
    component: User,  
    meta: { id: 1 }  
  }  
];

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 should see `user 1` displayed since we have `$route.meta.id` in our template.

Adding Transition Effect
========================

We can apply transition effects to `router-view` the same way as any other component.

For example, we can apply per-route transition by writing the following:

`src/index.js` :

```
const Foo = {  
  template: `  
    <transition name="slide">  
      <div>foo</div>  
    </transition>  
  `  
};

const Bar = {  
  template: `  
    <transition name="fade">  
      <div>bar</div>  
    </transition>  
  `  
};

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

const router = new VueRouter({  
  routes  
});

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

`src/styles.css` :

```
.fade-enter-active,  
.slide-enter-active {  
  transition: all 0.3s ease;  
}  
.fade-leave-active,  
.slide-leave-active {  
  transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);  
}  
.fade-enter,  
.fade-leave-to,  
.slide-enter,  
.slide-leave-to {  
  transform: translateX(10px);  
  opacity: 0;  
}
```

`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>  
    <link href="src/styles.css" type="text/css" />  
  </head>  
  <body>  
    <div id="app">  
      <router-link to="foo">Foo</router-link>  
      <router-link to="bar">Bar</router-link>  
      <router-view></router-view>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>
```

Then we see that there’s fade effect as we transition from one route to another by clicking the links.

We can then use different names for each route.

Route-Based Dynamic Transition
==============================

We can also do route based dynamic transitions by combining a watcher for `$route` and dynamically setting the transition name as follows:

`src/index.js` :

```
const Foo = {  
  template: ` 
    <transition name="slide">  
      <div>foo</div>  
    </transition>  
  `  
};

const Bar = {  
  template: `  
    <transition name="fade">  
      <div>bar</div>  
    </transition>  
  `  
};

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

const router = new VueRouter({  
  routes  
});

new Vue({  
  el: "#app",  
  router,  
  data: {  
    transitionName: ""  
  },  
  watch: {  
    $route(to, from) {  
      this.transitionName = to.path === "/bar" ? "slide-right" : "slide-left";  
    }  
  }  
});
```

`src/styles.css` :

```
.slide-left-enter-active,  
.slide-right-enter-active {  
  transition: all 0.3s ease;  
}  

.slide-left-leave-active,  
.slide-right-leave-active {  
  transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);  
}  
.slide-right-enter,  
.slide-right-leave-to {  
  transform: translateX(10px);  
  opacity: 0;  
}

.slide-left-enter,  
.slide-left-leave-to {  
  transform: translateX(-10px);  
  opacity: 0;  
}
```

`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>  
    <link href="src/styles.css" type="text/css" />  
  </head>  
  <body>  
    <div id="app">  
      <router-link to="foo">Foo</router-link>  
      <router-link to="bar">Bar</router-link>  
      <transition :name="transitionName">  
        <router-view></router-view>  
      </transition>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>
```

Then when we click on `Foo` , `bar` fades away by sliding to the left. And when we click `Bar` , `foo` fades away by sliding to the right.

Conclusion
==========

We can add meta fields to store extra data about a route. We can access it via navigation guards’ parameters or the `$route` object in components.

Like any other component, we can apply transition effects to `router-view` . All transition API work with `router-view` .