DEV Community

Cover image for Vue Class Components with TypeScript
Philip John Basile
Philip John Basile Subscriber

Posted on • Edited on

Vue Class Components with TypeScript

This is an old topic but the Vue Community is still stuck on Vue2 when it comes to professional projects and I think this little tidbit will help if you encounter some old code.

Vue Class Components provide a more familiar syntax for writing Vue components using classes instead of objects. When combined with TypeScript, you get static typing, better autocompletion, and improved type checking. To get started with Vue Class Components and TypeScript, follow these steps:

Install dependencies:

Make sure you have Node.js and npm installed. Then, create a new project using Vue CLI:

npm install -g @vue/cli
vue create my-project
Enter fullscreen mode Exit fullscreen mode

Choose "Manually select features" and select TypeScript, along with any other features you need.

Install Vue Class Component:

Navigate to your new project folder and install the vue-class-component and vue-property-decorator packages:

cd my-project
npm install vue-class-component vue-property-decorator
Enter fullscreen mode Exit fullscreen mode

Update main.ts:

In src/main.ts, make sure to import Vue from 'vue' and use the necessary plugins:

import Vue from 'vue';
import App from './App.vue';

Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App),
}).$mount('#app');
Enter fullscreen mode Exit fullscreen mode

Create a class-based component:

In src/components, create a new file called HelloWorld.vue. This will be your class-based component:

<template>
  <div>
    <h1>{{ message }}</h1>
    <button @click="onClick">Click me</button>
  </div>
</template>

<script lang="ts">
import { Vue, Component, Prop } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
  @Prop({ default: 'Hello, World!' }) private message!: string;

  private onClick() {
    this.$emit('clicked');
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

Here's a breakdown of the code:

  • Import Vue, Component, and Prop from the vue-property-decorator package.
  • Use the @Component decorator to define the class as a Vue component.
  • Extend the Vue class to create your own component class.
  • Use the @prop decorator to define props for the component.
  • Define methods and other component properties as class members.

Use your class-based component:

Now you can use your HelloWorld component in another Vue component:

<template>
  <div>
    <HelloWorld @clicked="onHelloWorldClicked" />
  </div>
</template>

<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';
import HelloWorld from './components/HelloWorld.vue';

@Component({
  components: {
    HelloWorld,
  },
})
export default class App extends Vue {
  private onHelloWorldClicked() {
    console.log('HelloWorld component was clicked');
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

That's it! You now know the basics of using Vue Class Components with TypeScript. This setup allows you to leverage TypeScript's type checking and code autocompletion capabilities while working with Vue components.

To convert Vue Class Components to normal Vue components, you will need to rewrite the component using the object-based syntax. Here's an example of how you can convert a simple class-based component to a normal Vue component:

<!-- class-based component -->
<template>
  <div>
    <h1>{{ message }}</h1>
  </div>
</template>

<script lang="ts">
import { Vue, Component } from 'vue-property-decorator';

@Component
export default class HelloWorld extends Vue {
  private message = 'Hello, World!';
}
</script>
Enter fullscreen mode Exit fullscreen mode
<!-- converted normal Vue component -->
<template>
  <div>
    <h1>{{ message }}</h1>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';

export default defineComponent({
  data() {
    return {
      message: 'Hello, World!',
    };
  },
});
</script>
Enter fullscreen mode Exit fullscreen mode

Here's what we did:

  • Remove the @Component decorator and extend the Vue class.
  • Define a data function that returns an object with the component's properties and data.
  • Use the defineComponent function from the vue package to create the component.

Note that the data function is used to define the component's data, which is similar to the properties defined with the @prop decorator in Vue Class Components. You can also define other component options, such as methods, computed, and watchers, using similar functions within the defineComponent function.

Keep in mind that the Vue Class Component syntax is often preferred due to its improved readability and reusability. If you are converting a large or complex component, consider refactoring it into smaller, reusable components using Vue Class Components.

If you enjoy my technology-focused articles and insights and wish to support my work, feel free to visit my Ko-fi page at https://ko-fi.com/philipjohnbasile. Every coffee you buy me helps keep the tech wisdom flowing and allows me to continue sharing valuable content with our community. Your support is greatly appreciated!

Top comments (0)