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
.