Vue Property Decorator

9.1.2 · active · verified Sun Apr 19

vue-property-decorator is a library that provides a set of TypeScript decorators for creating Vue components with a class-based syntax, building on top of `vue-class-component`. It allows developers to define props, methods, computed properties, watchers, and lifecycle hooks using declarative decorators rather than the traditional Vue options API. This approach aims to improve readability and maintainability, especially in larger TypeScript projects. The current stable version is 9.1.2. While its release cadence has varied, it remains actively maintained, though primarily for Vue 2 applications. Its key differentiator is simplifying common Vue patterns into concise, type-safe decorator declarations, providing a more object-oriented way to define components compared to the standard options API or the newer Vue 3 Composition API. It is largely considered a bridge for those who prefer class-based component development within the Vue 2 ecosystem.

Common errors

Warnings

Install

Imports

Quickstart

This Vue Single File Component (SFC) demonstrates basic usage of `@Component`, `@Prop`, `@Emit`, and `@Watch` decorators to create an interactive button with typed properties and event handling.

<!-- MyButton.vue -->
<template>
  <button :disabled="disabled" @click="onClick">
    {{ formattedLabel }} ({{ internalClickCount }})
  </button>
</template>

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

@Component
export default class MyButton extends Vue {
  @Prop({ type: String, default: 'Click Me' })
  readonly label!: string;

  @Prop({ type: Boolean, default: false })
  readonly disabled!: boolean;

  private internalClickCount: number = 0;

  get formattedLabel(): string {
    return this.label.toUpperCase();
  }

  @Emit('button-clicked')
  onClick(event: MouseEvent): number {
    this.internalClickCount++;
    console.log(`Button clicked! New count: ${this.internalClickCount}`);
    return this.internalClickCount;
  }

  @Watch('internalClickCount')
  onInternalClickCountChange(newValue: number, oldValue: number) {
    console.log(`Click count changed from ${oldValue} to ${newValue}`);
  }

  mounted() {
    console.log('MyButton mounted!');
  }
}
</script>

<style scoped>
button {
  padding: 10px 20px;
  background-color: #42b983;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
}
button:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}
</style>

view raw JSON →