In September of last year, Evan You (creator of Vue.js) announced plans for the next major version of the library. Vue 3.0 will feature an improved experience for TypeScript users, including native support for class-based components, and better support for type inference when writing code.
The great news is, you donât have to wait until version 3.0 is released (predicted for Q3 of 2019) to start writing your Vue apps in TypeScript. Vueâs command-line tool, Vue CLI, comes with options for starting projects with the TypeScript build tooling pre-configured and includes the officially supported vue-class-component module, allowing you to write your Vue components as TypeScript classes.
This article assumes some familiarity with both Vue and the basics of TypeScript. Letâs take a look and see how you can start taking advantage of static typing and class-based components in your code today.
Starting a Vue + TypeScript ProjectOne hurdle to getting started with TypeScript can be configuring the necessary build tooling. Thankfully, Vue has us covered there with the Vue CLI. We can use it to create a project for us with the TypeScript compiler set up and ready to go.
Letâs briefly walk through creating a new Vue project with TypeScript support.
From the terminal/command line (and assuming you have Node.js installed), run the following command to install Vue CLI globally:
npm install -g @vue/cli
Next, letâs create a new project, specifying the name of the project:
vue create vue-typescript-demo
This will also be the name of the sub-folder the project is installed to. Once you hit Enter , youâll be prompted to choose either the default preset, or to manually select the options you wish to have installed.
Choose the manual option, and youâll be presented with a further set of options. The essential option is, obviously, TypeScript, but you might also want to select Vuex as weâll be checking out some Vuex-specific decorators later on.
Having selected your project options, the next screen will ask you if you want to use the class-style component syntax. Say yes to this. Youâll then be asked if you want to âUse Babel alongside TypeScript for auto-detected polyfillsâ. This is a good idea for projects where youâll be supporting older browsers. Answer the remaining questions as you see fit, and the installation process should start.
A Note on Editor/IDE SupportMany code editors and IDEs now have support for TypeScript. Among paid solutions, JetBrains software (e.g. WebStorm, PhpStorm) has excellent support for both Vue and TypeScript. If youâre looking for a free alternative, my recommendation is Microsoftâs Visual Studio Code: combined with the Vetur extension it provides great auto-completion and type checking.
Class-based ComponentsLetâs start by looking at how to write Vue components using classes. While this feature is not limited to TypeScript, using class-based components helps TS provide better type checking and, in my opinion, makes for cleaner, more maintainable components.
Letâs take a look at the syntax. If you followed along with the previous section and used Vue CLI to create a new project, go into the project directory, into the src sub-folder, and open App.vue. What weâre interested in here is the <script>
section, as itâs the only part that differs from a standard Vue single-file-component (SFC).
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import HelloWorld from './components/HelloWorld.vue';
@Component({
components: {
HelloWorld,
},
})
export default class App extends Vue {}
</script>
Notice that the <script>
tag itself has a lang
attribute of ts set. This is important for the build tools and your editor to correctly interpret the code as TypeScript.
In order to declare a class-based component, you need to create a class that extends vue
(here itâs imported from the vue-property-decorator
package rather than the vue module directly).
The class declaration needs to be preceded by the @Component
decorator:
@Component
class MyComponent extends Vue {}
As you might have noticed in the code from the App.vue component, the decorator can also accept an object, which can be used to specify the components
, props
, and filters
options for the component:
@Component({
components: { MyChildComponent },
props: {
id: {
type: String,
required: true
}
},
filters: {
currencyFormatter
}
})
class MyComponent extends Vue {}
Data properties
When declaring object-based components, youâll be familiar with having to declare your componentâs data properties as a function that returns a data object:
{
data: () => ({
todos: [],
})
}
⦠whereas with class-based components, we can declare data properties as normal class properties:
@Component
class TodoList extends Vue {
todos: [];
}
Computed properties
Another advantage of using classes as components is the cleaner syntax for declaring computed properties, using getter methods:
@Component
class TodoList extends Vue {
get uncompletedTodos() {
return this.todos.filter(todo => todo.done === false);
}
}
Likewise, you can create writable computed properties by using a setter method:
set fullName(value: string) {
let names = newValue.split(' ');
this.firstName = names[0];
this.lastName = names[names.length - 1];
}
Methods
Component methods can be declared in a similarly clean way, as class methods:
@Component
class TodoList extends Vue {
addTodo(text) {
this.todos.push({ text, done: false });
}
}
In my opinion, the simple syntax for declaring methods, data properties, and computed properties makes writing and reading class-based components nicer than the original object-based ones.
DecoratorsWe can take things a step further, using the additional decorators provided by the vue-property-decorator package. It provides six additional decorators for authoring class-based components:
Letâs take a look at three of them that youâll probably find the most useful.
@PropRather than passing a props
configuration object to the @Component
decorator, you can use the @Props
decorator to declare your props as class properties.
@Component
class TodoItem extends Vue {
@Prop
todo;
}
As with other decorators, @Prop
can accept various arguments, including a type, an array of types, or an options object:
@Prop(String)
name;
@Prop([String, Null])
title;
@Prop({ default: true })
showDetails;
When using with TypeScript, you should suffix your prop names with the non-null operator (!) to tell the compiler that the prop will have a non-null value (as TS is not aware these values will be passed into the component when itâs initialized):
@Prop(String) name!: string;
Note that, as shown above, itâs perfectly OK to put the decorator and the property declaration on one line if you want.
@EmitAnother handy decorator is @Emit
, allowing you to emit an event from any class method. The event emitted will use the name of the method (with camelCase names being converted to kebab-case), unless an alternative event name is passed to the decorator.
If the method returns a value, this will be emitted as the eventâs payload, along with any arguments passed to the method.
@Emit()
addTodo() {
return this.newTodo;
}
The above code will emit an âadd-todoâ event with the value of this.newTodo
as the payload.
Creating watchers is nice and simple with this decorator. It takes two arguments: the name of the property being observed, and an optional options object.
@Watch('myProp')
onMyPropChanged(val: string, oldVal: string) {
}
@Watch('myObject', { immediate: true, deep: true })
onMyObjectChanged(val: MyObject, oldVal: MyObject) { }
Summing Up
I hope this article has shown you that starting to write your Vue apps in TypeScript doesnât have to be a headache. By using the CLI to start new projects, you can quickly set up the necessary build tooling. The included support for class-based components and the additional decorators will have you writing clean, idiomatic TypeScript in no time!
Want to learn Vue.js from the ground up? Get an entire collection of Vue books covering fundamentals, projects, tips and tools & more with SitePoint Premium. Join now for just $9/month or try our 7 day free trial.
Frequently Asked Questions (FAQs) about Class-Based Vue.js with TypeScript What are the benefits of using TypeScript with Vue.js?TypeScript offers static typing, which can be a significant advantage when developing large-scale applications. It helps catch errors early in the development process, making the code more robust and maintainable. TypeScript also provides better autocompletion, navigation, and refactoring services, making the development process more efficient. When used with Vue.js, TypeScript allows for a more structured and scalable codebase, making it easier to manage and develop complex applications.
How do I set up a Vue.js project with TypeScript?Setting up a Vue.js project with TypeScript involves a few steps. First, you need to install Vue CLI, if you havenât already. Then, create a new project using Vue CLI and select TypeScript as a feature during the creation process. Vue CLI will set up a TypeScript configuration for you. You can then start writing Vue components using TypeScript.
What is a class-based component in Vue.js?A class-based component in Vue.js is a way of defining components using ES6 classes. This approach can make your components more readable and easier to understand, especially for developers coming from an object-oriented programming background. Class-based components also work well with TypeScript, allowing you to leverage TypeScriptâs features like static typing and interfaces.
How do I define a class-based component in Vue.js with TypeScript?To define a class-based component in Vue.js with TypeScript, you need to use the vue-class-component
decorator. This decorator allows you to write your component as an ES6 class. Inside the class, you can define your data, methods, and lifecycle hooks just like you would in a regular Vue component.
Yes, you can use Vue.js directives in class-based components. The syntax is the same as in regular Vue components. You can use directives like v-model
, v-if
, v-for
, etc., in your template.
In class-based components, you can define props using the @Prop
decorator. This decorator allows you to specify the type of the prop and whether itâs required or has a default value.
In class-based components, you can define computed properties as getter methods in your class. The result of the getter method will be cached and only re-evaluated when its dependencies change.
How do I use watchers in class-based components?In class-based components, you can define watchers using the @Watch
decorator. This decorator allows you to specify the property to watch and the method to call when the property changes.
Yes, you can use mixins in class-based components. You can define a mixin as a class and then use the @Mixins
decorator to include it in your component.
The Vue.js Composition API works well with TypeScript. You can define your reactive data and functions inside the setup
method and use TypeScript to type them. This allows you to leverage TypeScriptâs static typing and autocompletion features, making your code more robust and easier to develop.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4