Other articles in the series
The front-end related code for this post is available at here.
Getting started with Vuejs and Typescript
Typescript is like Javascript with types. Types can help us in finding a category of bugs and help us in refactoring code easily. For setting up a project we use vue-cli 3. To install it, issue the below command.
npm install -g @vue/cli
Once we have installed, it is time to create our project.
Creating the Project
A new project can be created using vue create.
vue create shop
The console will ask a few questions and once it is finished we have a bare minimum working vuejs app. I chose typescript, vue-router, vuex, dart-sass, babel, pwa, unit-jest and e2e-cypress. Once it is finished start the dev server.
Starting Vue Development Server
cd shop
npm run serve
Now we got the vue running at port 8080.
Ok, so now we got vue running, but how does it work ?. Lets take a dive into the basic concepts and working of Vue with Typescript.
Vue starts its execution from the main.ts file inside the src/main.ts file.
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import './registerServiceWorker';
Vue.config.productionTip = false;
new Vue({
router,
store,
render: (h) => h(App),
}).$mount('#app');
Routing with Vue-router
Here we make a new Vue instance with router, store and an app. Router takes care of the routing to views according to the url.
src/router.ts
import Vue from 'vue';
import Router from 'vue-router';
import Home from './views/Home.vue';
Vue.use(Router);
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home,
},
{
path: '/about',
name: 'about',
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ './views/About.vue'),
},
],
});
Vue Components
As you can see here when the path is /(root) we route to component Home. Components are self-contained, reusable blocks in Vue. Vue components have a template part, which resides inside <template> tag, where we will write html elements. Another part <style> takes care of the styling and the <script> tag part holds the logic for the component. The files ending with .vue are single-file components. Here we see Home.vue file is imported. Lets see what is inside it, so that we know what we will get when we visit the /.
<template>
<div class="home">
<img src="../assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HelloWorld from '@/components/HelloWorld.vue'; // @ is an alias to /src
@Component({
components: {
HelloWorld,
},
})
export default class Home extends Vue {}
</script>
We see HelloWorld imported from components folder. And it is passed to @Component Typescript decorator. The @Component is a decorator, which tells vue which components are used in the current component, ie. inside Home component. Since we only use the HelloWorld, we list it there. And we use the HelloWorld component inside the <template> tag. It is like embedding the contents of that component, inside our own. You can consider it as small building blocks which make up our current view.
Lets look at the HelloWorld component itself. I omitted unimportant pieces below, like styling information and links.
<template>
<div class="hello">
<h1>{{ msg }}</h1>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
@Component
export default class HelloWorld extends Vue {
@Prop() private msg!: string;
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
</style>
Vue Component Props
Here we see a new decorator, the @Prop decorator. It is another decorator for making use of vue props. Props are messages which we pass to the components. For example here we see that we are using {{msg}} inside our <template>, but we haven’t assigned a value to it anywhere in our component. So from where, will we get this value ?. The props is the answer. Component which embeds this components provides it to us via props. In this case the Home component gives it to us like below. Notice the msg=…value.
<HelloWorld msg="Welcome to Your Vue.js + TypeScript App"/>
So our {{msg}} gets the value Welcome to Your Vue.js …..
State management in Vue
Store is like a database where you store data from components. The store we use here Vuex is a reactive store, which means all components which use a specific data will be automatically updated, if that data changes.
src/store.ts
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
});
We will discuss the state, mutations and actions in a later part of the tutorial. If we notice the main.ts file, it passes the App.vue into the render function and mounts it to #app id in the public/index.html file. This means App.vue is the main/entry file.
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view/>
</div>
</template>
<script></script>
<style></style>
Inside the App.vue file we have two router-links. The router-link is a like a a href for router. router-link modifies the router view based on this link in accordance with the router.ts we discussed earlier. This results in changing of displayed component when the link is clicked. This can be seen by clicking the About button, which points to /about path, which is mapped to views/About.vue component inside router.ts.
The only step left is to mount the vue to some tag in HTML file, which is done by the $mount. Here it mounts to tag with id #app. Head over to Official docs for an in depth explanation of Vue. The source code for client is available here.
In next part, we will discuss about adding multi language support to Vue.