{"id":12551,"library":"vue-property-decorator","title":"Vue Property Decorator","description":"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.","status":"active","version":"9.1.2","language":"javascript","source_language":"en","source_url":"https://github.com/kaorun343/vue-property-decorator","tags":["javascript","vue","typescript","decorator"],"install":[{"cmd":"npm install vue-property-decorator","lang":"bash","label":"npm"},{"cmd":"yarn add vue-property-decorator","lang":"bash","label":"yarn"},{"cmd":"pnpm add vue-property-decorator","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core Vue functionality for component rendering and reactivity.","package":"vue","optional":false},{"reason":"vue-property-decorator builds directly on top of vue-class-component, providing additional decorators.","package":"vue-class-component","optional":false}],"imports":[{"note":"@Component is a default export from 'vue-class-component', which is a peer dependency of vue-property-decorator. It's essential for declaring class-based components.","wrong":"import { Component } from 'vue-class-component'","symbol":"Component","correct":"import Component from 'vue-class-component'"},{"note":"Named export for defining component props with type checking and options.","wrong":"import Prop from 'vue-property-decorator'","symbol":"Prop","correct":"import { Prop } from 'vue-property-decorator'"},{"note":"Use the @Emit decorator on methods to declare custom events that the component can emit.","wrong":"const { Emit } = require('vue-property-decorator')","symbol":"Emit","correct":"import { Emit } from 'vue-property-decorator'"},{"note":"Named export for reacting to changes in data properties, similar to the `watch` option in Vue.","symbol":"Watch","correct":"import { Watch } from 'vue-property-decorator'"},{"note":"The base Vue constructor is a default export from the 'vue' package.","wrong":"import { Vue } from 'vue'","symbol":"Vue","correct":"import Vue from 'vue'"},{"note":"Named exports for dependency injection features (provider/consumer pattern).","symbol":"Inject, Provide","correct":"import { Inject, Provide } from 'vue-property-decorator'"}],"quickstart":{"code":"<!-- MyButton.vue -->\n<template>\n  <button :disabled=\"disabled\" @click=\"onClick\">\n    {{ formattedLabel }} ({{ internalClickCount }})\n  </button>\n</template>\n\n<script lang=\"ts\">\nimport { Component, Prop, Emit, Watch, Vue } from 'vue-property-decorator';\n\n@Component\nexport default class MyButton extends Vue {\n  @Prop({ type: String, default: 'Click Me' })\n  readonly label!: string;\n\n  @Prop({ type: Boolean, default: false })\n  readonly disabled!: boolean;\n\n  private internalClickCount: number = 0;\n\n  get formattedLabel(): string {\n    return this.label.toUpperCase();\n  }\n\n  @Emit('button-clicked')\n  onClick(event: MouseEvent): number {\n    this.internalClickCount++;\n    console.log(`Button clicked! New count: ${this.internalClickCount}`);\n    return this.internalClickCount;\n  }\n\n  @Watch('internalClickCount')\n  onInternalClickCountChange(newValue: number, oldValue: number) {\n    console.log(`Click count changed from ${oldValue} to ${newValue}`);\n  }\n\n  mounted() {\n    console.log('MyButton mounted!');\n  }\n}\n</script>\n\n<style scoped>\nbutton {\n  padding: 10px 20px;\n  background-color: #42b983;\n  color: white;\n  border: none;\n  border-radius: 5px;\n  cursor: pointer;\n}\nbutton:disabled {\n  background-color: #cccccc;\n  cursor: not-allowed;\n}\n</style>","lang":"typescript","description":"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."},"warnings":[{"fix":"Ensure `vue-class-component@^7.0.0` is installed alongside `vue-property-decorator@8.x.x` or newer versions.","message":"Major version 8.0.0 introduced a breaking change requiring `vue-class-component` version 7.x.x. Upgrading `vue-property-decorator` to v8+ without simultaneously upgrading `vue-class-component` will lead to runtime errors.","severity":"breaking","affected_versions":">=8.0.0"},{"fix":"For Vue 3, consider using the Composition API directly, or explore alternative libraries specifically built for Vue 3 if a class-based component structure is essential.","message":"`vue-property-decorator` is designed exclusively for Vue 2 applications. It is not compatible with Vue 3's Composition API, `script setup`, or its updated reactivity system.","severity":"gotcha","affected_versions":"*"},{"fix":"Add or ensure `\"experimentalDecorators\": true` and `\"emitDecoratorMetadata\": true` are set under `compilerOptions` in your `tsconfig.json`.","message":"TypeScript decorators, which `vue-property-decorator` relies on, require specific compiler options (`experimentalDecorators` and `emitDecoratorMetadata`) to be enabled in your `tsconfig.json`.","severity":"gotcha","affected_versions":"*"},{"fix":"For new projects or ongoing long-term maintenance, plan migration to Vue 3 to ensure security, access to modern features, and continued official support.","message":"Vue 2, the core framework that `vue-property-decorator` targets, reached End of Life (EOL) on December 31, 2023. While `vue-property-decorator` itself is actively maintained, the underlying Vue 2 platform is no longer receiving official support or updates from the Vue team.","severity":"deprecated","affected_versions":"*"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Verify that `vue-class-component` is compatible with your `vue-property-decorator` version (e.g., `vue-class-component@^7.0.0` for `vue-property-decorator@8.x.x+`). Ensure `import Component from 'vue-class-component'` is used correctly and that TypeScript decorators are enabled in `tsconfig.json`.","cause":"This often occurs due to a mismatch in `vue-class-component` versions, an incorrect import of `@Component`, or decorators not being properly enabled.","error":"TypeError: Cannot read properties of undefined (reading 'prototype')"},{"fix":"Add or update your `tsconfig.json` under `compilerOptions` with: `\"experimentalDecorators\": true, \"emitDecoratorMetadata\": true`.","cause":"Your TypeScript configuration is missing the required flags to enable decorator syntax.","error":"Error: Decorators are not enabled."},{"fix":"Run `npm install vue-property-decorator vue-class-component vue` or `yarn add vue-property-decorator vue-class-component vue` to ensure all peer dependencies are installed, and check your import statements for typos.","cause":"The package is either not installed, or your import path is incorrect, or TypeScript cannot resolve its types.","error":"Cannot find module 'vue-property-decorator' or its corresponding type declarations."}],"ecosystem":"npm"}