If we prefer to use classes, we can use the class-based components API that comes with Vue.
In this article, we’ll look at how to developing Vue apps with class-based components.
TypeScript, Superclasses, and Mixins
We can add props and inherit superclass components with the mixins
method in our Vue TypeScript project.
For instance, we can write:
<template>
<div>
<p>{{ message }}</p>
</div>
</template>
<script lang="ts">
import Vue from "vue";
import Component, { mixins } from "vue-class-component";
const GreetingProps = Vue.extend({
props: {
name: String,
},
});
@Component
class Super extends Vue {
lastName = "smith";
}
@Component
export default class HelloWorld extends mixins(GreetingProps, Super) {
get message(): string {
return `Hello, ${this.name} ${this.lastName}`;
}
}
</script>
We create the Super
component class with the 1astName
property.
And we have the GreetProps
class that we create with the Vue.extend
method so we can accept props in a way that’s acceptable by TypeScript.
Then we call the mixins
method with the GreetProps
and Super
methods so we can inherit from both classes.
We inherit from both classes, so this.name
is 'james'
and this.lastName
is 'smith'
.
We can define properties with type definitions.
For instance, we can write:
<template>
<div>
<p v-for="p of persons" :key="p">{{ p.firstName }} {{ p.lastName }}</p>
</div>
</template>
<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
interface Person {
firstName: string;
lastName: string;
}
@Component
export default class HelloWorld extends Vue {
persons!: Person[] = [
{ firstName: "james", lastName: "smith" },
{ firstName: "jane", lastName: "doe" },
];
}
</script>
We create the Person
interface and use that for defining the type of the persons
class property.
The !
means the class property isn’t nullable.
Now if the persons
array entries have extra properties, we’ll get an error from the TypeScript compiler.
Refs and TypeScript
To define and assign refs with TypeScript class-based Vue components, we write:
<template>
<div>
<input ref="input" />
</div>
</template>
<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
@Component
export default class HelloWorld extends Vue {
$refs!: {
input: HTMLInputElement;
};
mounted() {
this.$refs.input.focus();
}
}
</script>
We have to set the type for each $refs
property we assign.
input
is an HTML input element, so we set it to the HTMLInputElement
type.
Then we call call focus
on it to focus it.
With the type annotation added, we get autocomplete when we type in the code in the mounted
hook.
Hooks Autocomplete
To add autocomplete for hooks, we write:
main.ts
import Vue from "vue";
import App from "./App.vue";
import "vue-class-component/hooks";
Vue.config.productionTip = false;
new Vue({
render: (h) => h(App)
}).$mount("#app");
App.vue
<template>
<div id="app">
<HelloWorld />
</div>
</template>
<script lang='ts'>
import HelloWorld from "./components/HelloWorld.vue";
export default {
name: "App",
components: {
HelloWorld,
},
};
</script>
components/HelloWorld.vue
<template>
<div>
{{ message }}
</div>
</template>
<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";
@Component
export default class HelloWorld extends Vue {
data() {
return {
message: "hello world",
};
}
}
</script>
Once we add:
import "vue-class-component/hooks";
in main.ts
, we get autocomplete when we type in data
in the HelloWorld
component.
Conclusion
We can add hooks autocomplete, mixins and superclass inheritance, and refs type annotation within our Vue class-based components written in TypeScript.