Adding custom hooks to vue-class-component
On Vue, it's possible to add hooks to its life cycle through the Plugins application programming interface (API). The most basic example is the vue-router with the navigation guards, such as the beforeRouterEnter and beforeRouterLeave functions hooks.
The hooks, as the name implies, are little functions that are called each time something will happen.
You can take advantage of the hooks and make them more powerful, adding new functionalities to your components, such as checking for special security access, adding meta search engine optimization (SEO), or even pre-fetching data.
Getting ready
The pre-requisite for this recipe is as follows:
- Node.js 12+
The Node.js global objects that are required are as follows:
- @vue/cli
- @vue/cli-service-global
How to do it...
First, we need to create our Vue CLI project. We can use the one we created in the last recipe or start a new one. To find how to create a Vue CLI project with TypeScript, please check the 'Adding TypeScript to a Vue CLI project' recipe.
Now, follow these steps to add custom hooks to your Vue project using TypeScript and vue-class-component:
- We need to add vue-router to the project. This can be done with the Vue CLI project creation or in the Vue UI interface after the project has been created.
- Open Terminal (macOS or Linux) or Command Prompt/PowerShell (Windows) and execute the npm run serve command, and you will see that the vue-router is working and that there are two working routers: home and about.
- Let's start creating and naming our hooks to register on the main application. To do this, we need to create a vue-router.js file inside the src/classComponentsHooks folder:
import Component from 'vue-class-component';
Component.registerHooks([
'beforeRouteEnter',
'beforeRouteLeave',
]);
- We need to import this file to the main.ts file as it needs to be called before the application final build:
import './classComponentsHooks/vue-router';
import Vue from 'vue';
import App from './App.vue';
import router from './router';
Vue.config.productionTip = false;
new Vue({
router,
render: h => h(App),
}).$mount('#app');
- We now have the hooks registered on the vue-class-component and they can be used inside the TypeScript components.
- We need to create a new router location called Secure.vue in the src/views folder. The secure page will have a password to enter, vuejs. When the user enters this password, the router guard will grant permission, and the user can see the page. If the password is wrong, the user will be taken back to the home page. When they leave the page, an alert will show a message to the user:
<template>
<div class="secure">
<h1>This is an secure page</h1>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { Route, RawLocation } from 'vue-router';
type RouteNext = (to?: RawLocation | false | ((vm: Vue) => any) |
void) => void;
@Component
export default class Home extends Vue {
beforeRouteEnter(to: Route, from: Route, next: RouteNext) {
const securePassword = 'vuejs';
const userPassword = prompt('What is the password?');
if (userPassword === securePassword) {
next();
} else if (!userPassword) {
next('/');
}
}
beforeRouteLeave(to: Route, from: Route, next: RouteNext) {
alert('Bye!');
next();
}
}
</script>
- Now with our page done, we need to add it to the router.ts file to be able to call it in the Vue application:
import Vue from 'vue';
import Router from 'vue-router';
import Home from './views/Home.vue';
Vue.use(Router);
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: Home,
},
{
path: '/about',
name: 'about',
component: () => import('./views/About.vue'),
},
{
path: '/secure',
name: 'secure',
component: () => import('./views/Secure.vue'),
},
],
});
- With the route added and the view created, the final step is to add the link to the main App.vue file, and we will have a component with an integrated hook on it:
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/secure">Secure</router-link>
</div>
<router-view/>
</div>
</template>
<style lang="stylus">
#app
font-family 'Avenir', Helvetica, Arial, sans-serif
-webkit-font-smoothing antialiased
-moz-osx-font-smoothing grayscale
text-align center
color #2c3e50
#nav
padding 30px
a
font-weight bold
color #2c3e50
&.router-link-exact-active
color #42b983
</style>
How it works...
The class component needs to understand what are the navigation guards that are being added to the Vue prototype before executing the Vue application. Because of this, we needed to import the custom hooks on the first line of the main.ts file.
In the component, with the hooks registered, it's possible to add them as methods because the vue-class-component has made all those custom imports into base methods for the component decorator.
We used two of the vue-router navigation guards' hooks. Those hooks are called each time a route will enter or leave. The first two parameters we didn't use, the to and from parameters, are the ones that carry information about the future route and the past route.
The next function is always required because it executes a route change. If no argument is passed in the function, the route will continue with the one that was called, but if you want to change the route on the fly, it is possible to pass an argument to change where the user will go.
See also
Find more about vue-router navigation guards at https://router.vuejs.org/guide/advanced/navigation-guards.html.
Find more about the vue-class-component hooks at https://github.com/vuejs/vue-class-component#adding-custom-hooks.