How to Create Vue Components Using TypeScript and Vueify

  Programming

TypeScript has become very popular these days, and I’m sure there are some of you who’d prefer using it while creating Vue components. In this tutorial, I’ll show you how to use TypeScript—along with vue-class-component, Browserify, and Vueify—to create a simple Vue 2.x component.

Note that we won’t be using any starter templates in this tutorial. In fact, we won’t be using Vue CLI at all. Instead, we’ll install everything we need manually, and also build our project manually. Why? Well, to gain a better understanding of how things work.

1. Project Setup

Let’s start by creating a new directory for our project.

mkdir my-app && cd my-app

We can now generate a package.json file for our project using npm.

npm init

To be able to use the TypeScript transpiler from the command-line, install it globally.

npm install -g typescript

And now, install Vue and vue-class-component, a TypeScript decorator for Vue components, as your project’s dependencies.

npm install -S vue vue-class-component

Additionally, you must install TypeScript definitions for es6-promise.

npm install -S @types/es6-promise

2. Create a Component

Let us now create a simple component. We’ll do so by creating two files:

touch dog.ts
touch Dog.vue

As you might expect, dog.ts is going to contain our component’s TypeScript code, and Dog.vue will contain the layout.

First, open dog.ts using your favorite code editor.

Inside it, import both vue and vue-class-component.

import * as Vue from 'vue'
import Component from 'vue-class-component'

And now, create a new class called Dog, which extends Vue. Additionally, use the @Component decoration to specify the properties of the component.

You must also mention the same properties as member variables of the class.

Any additional member variable you add will become the data of the component.

@Component({
    props: {
        breed: String,
        age: Number,
        owner: String    
    }
})
export default class Dog extends Vue {
    breed: string
    age: number
    owner: string

    description: string = ""

    mounted() {
        this.description = "I have a " + this.breed + 
                           ". It is " + this.age + " years old.";
    }
}

In the above code, you can see that breed, age, and owner are properties. And description is part of the Dog component’s data. Lastly, the mounted() lifecycle method is being used to initialize the description using the values of the props.

That’s all you need to add. Our component’s TypeScript code is ready. It was easy, wasn’t it?

Now, in the command-line, transpile the TypeScript file using tsc to generate a JavaScript file. Don’t forget to add the --experimentalDecorators flag to the command.

tsc dog.ts --experimentalDecorators

If there are no errors, at this point, you’ll have a dog.js file.

Let us now define our component’s layout inside the .vue file. So, open Dog.vue.

Inside it, we’ll add some very basic HTML code. We’ll also use the mustache syntax to display some of our component’s properties and data.

<template>
	<div>
        <h5>Message from {{ owner }}</h5>
		{{ description }}
	</div>
</template>

Additionally, to link the layout to our code, we must use a <script> tag. For now, point it to the generated dog.js file.

<script src="./dog.js"></script>

Our component is now ready. To be able to use it, create a new file called start.js and import both vue and Dog.vue inside it.

Next, use the constructor of Vue to render a new Dog element. You can use props to specify the values of its properties.

Accordingly, add the following code to start.js:

var Vue = require('vue')
var Dog = require('./Dog.vue')

new Vue({
   el: '#my-component-container',
   render: h => {
	return h(Dog, {props: {breed: "pug", age: 2, owner: "Hathi"}})
   }
})

Note that the Dog element will be added to an HTML element whose id is my-component-container. So, let us now create a new HTML page having it. I’m going to call the page start.html.

<html>
  <body>
    <div id="my-component-container"></div>
    <script src="build.js"></script>
  </body>
</html>

You can see that the page is using a new script file called build.js. We won’t be creating the file. Instead, we’ll be generating it by converting start.js using Browserify and Vueify.

So, install browserify globally, and vueify as a dev dependency.

npm install -g browserify
npm install -D vueify

You can now pass start.js to browserify and vueify to convert it into build.js.

browserify -t vueify -e start.js -o build.js

If you open start.html using a browser, you should be able to see your component working.

3. Configure Vueify

Transpiling the TypeScript file and using the generated JavaScript file in the component’s .vue file isn’t optimal. I mean, you can, but it will slow you down. Fortunately, we can configure vueify to do it automatically for us.

So, create a new file called vue.config.js. Inside it, add the following code:

var ts = require("typescript");

module.exports = {  
    customCompilers: {
        ts: function( content , cb ){
            var result = ts.transpileModule( content , { 
                                compilerOptions: { 
                                         module: ts.ModuleKind.CommonJS 
                                }
                         });
            cb( null , result.outputText )            
        }
    }
}

As you can see, the above code adds a custom compiler for <script> tags whose lang attribute is ts. It uses TypeScript’s Compiler API to convert TypeScript strings to JavaScript. More specifically, it uses the transpileModule() method to do so. The return value of the transpileModule() method is a JSON object containing two fields: outputText and diagnostics. The outputText field contains the transpiled JavaScript code, and we’ll be passing it to the callback function.

At this point, you can reopen Dog.vue and change its <script> tag to point to dog.ts directly. Alternatively, you can copy all the contents of dog.ts and paste them inside the tag.

<script src="./dog.ts" lang="ts"></script>

Lastly, run the following command to be able to use the TypeScript Compiler API in the project. Alternatively, you can install TypeScript as a dev dependency.

npm link typescript

And that’s all there is to it. You can run browserify again, and you’ll see that the component still works just fine.

browserify -t vueify -e start.js -o build.js

Conclusion

In this tutorial, you learned how to use vue-class-component, TypeScript, Vueify, and Browserify in your Vue projects. You might think that’s a lot of work. But, I hope you now have a better understanding of how all of them work together.

If you found this article useful, please share it with your friends and colleagues!