{"id":13424166,"url":"https://github.com/kaorun343/vue-property-decorator","last_synced_at":"2025-10-05T18:31:06.363Z","repository":{"id":37451260,"uuid":"49648180","full_name":"kaorun343/vue-property-decorator","owner":"kaorun343","description":"Vue.js and Property Decorator","archived":true,"fork":false,"pushed_at":"2023-04-11T05:28:16.000Z","size":948,"stargazers_count":5520,"open_issues_count":102,"forks_count":378,"subscribers_count":57,"default_branch":"master","last_synced_at":"2025-01-21T02:33:19.647Z","etag":null,"topics":["decorators","typescript","vue","vue-class-component","vue-property-decorator"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kaorun343.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2016-01-14T13:16:49.000Z","updated_at":"2025-01-20T09:58:57.000Z","dependencies_parsed_at":"2024-01-18T03:48:22.671Z","dependency_job_id":null,"html_url":"https://github.com/kaorun343/vue-property-decorator","commit_stats":{"total_commits":267,"total_committers":50,"mean_commits":5.34,"dds":0.696629213483146,"last_synced_commit":"e04872349bab357e6d08b01442f83abc9976eb50"},"previous_names":[],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaorun343%2Fvue-property-decorator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaorun343%2Fvue-property-decorator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaorun343%2Fvue-property-decorator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaorun343%2Fvue-property-decorator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kaorun343","download_url":"https://codeload.github.com/kaorun343/vue-property-decorator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235432166,"owners_count":18989468,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["decorators","typescript","vue","vue-class-component","vue-property-decorator"],"created_at":"2024-07-31T00:00:49.670Z","updated_at":"2025-10-05T18:31:06.030Z","avatar_url":"https://github.com/kaorun343.png","language":"TypeScript","funding_links":[],"categories":["Awesome Vue.js [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome)","TypeScript","实用库","语言资源库","公用事业","Components \u0026 Libraries","Utilities","Awesome Vue.js","Utilities [🔝](#readme)"],"sub_categories":["Libraries \u0026 Plugins","typescript","打字稿","Utilities","Typescript"],"readme":"\n# [DEPRECATED] Vue Property Decorator\n## ⚠️ Notice\nThis library is no longer actively maintained. If you still want to use classes, check out the community-maintained project [`vue-facing-decorator`](https://facing-dev.github.io/vue-facing-decorator/#/).\n\n---\n\n[![npm](https://img.shields.io/npm/v/vue-property-decorator.svg)](https://www.npmjs.com/package/vue-property-decorator)\n[![Build Status](https://travis-ci.org/kaorun343/vue-property-decorator.svg?branch=master)](https://travis-ci.org/kaorun343/vue-property-decorator)\n\nThis library fully depends on [vue-class-component](https://github.com/vuejs/vue-class-component), so please read its README before using this library.\n\n## License\n\nMIT License\n\n## Install\n\n```bash\nnpm i -S vue-property-decorator\n```\n\n## Usage\n\nThere are several decorators and 1 function (Mixin):\n\n- [`@Prop`](#Prop)\n- [`@PropSync`](#PropSync)\n- [`@Model`](#Model)\n- [`@ModelSync`](#ModelSync)\n- [`@Watch`](#Watch)\n- [`@Provide`](#Provide)\n- [`@Inject`](#Provide)\n- [`@ProvideReactive`](#ProvideReactive)\n- [`@InjectReactive`](#ProvideReactive)\n- [`@Emit`](#Emit)\n- [`@Ref`](#Ref)\n- [`@VModel`](#VModel)\n- `@Component` (**provided by** [vue-class-component](https://github.com/vuejs/vue-class-component))\n- `Mixins` (the helper function named `mixins` **provided by** [vue-class-component](https://github.com/vuejs/vue-class-component))\n\n## See also\n\n[vuex-class](https://github.com/ktsn/vuex-class/)\n\n### \u003ca id=\"Prop\"\u003e\u003c/a\u003e `@Prop(options: (PropOptions | Constructor[] | Constructor) = {})` decorator\n\n```ts\nimport { Vue, Component, Prop } from 'vue-property-decorator'\n\n@Component\nexport default class YourComponent extends Vue {\n  @Prop(Number) readonly propA: number | undefined\n  @Prop({ default: 'default value' }) readonly propB!: string\n  @Prop([String, Boolean]) readonly propC: string | boolean | undefined\n}\n```\n\nis equivalent to\n\n```js\nexport default {\n  props: {\n    propA: {\n      type: Number,\n    },\n    propB: {\n      default: 'default value',\n    },\n    propC: {\n      type: [String, Boolean],\n    },\n  },\n}\n```\n\n#### If you'd like to set `type` property of each prop value from its type definition, you can use [reflect-metadata](https://github.com/rbuckton/reflect-metadata).\n\n1. Set `emitDecoratorMetadata` to `true`.\n2. Import `reflect-metadata` **before** importing `vue-property-decorator` (importing `reflect-metadata` is needed just once.)\n\n```ts\nimport 'reflect-metadata'\nimport { Vue, Component, Prop } from 'vue-property-decorator'\n\n@Component\nexport default class MyComponent extends Vue {\n  @Prop() age!: number\n}\n```\n\n#### Each prop's default value need to be defined as same as the example code shown in above.\n\nIt's **not** supported to define each `default` property like `@Prop() prop = 'default value'` .\n\n### \u003ca id=\"PropSync\"\u003e\u003c/a\u003e `@PropSync(propName: string, options: (PropOptions | Constructor[] | Constructor) = {})` decorator\n\n```ts\nimport { Vue, Component, PropSync } from 'vue-property-decorator'\n\n@Component\nexport default class YourComponent extends Vue {\n  @PropSync('name', { type: String }) syncedName!: string\n}\n```\n\nis equivalent to\n\n```js\nexport default {\n  props: {\n    name: {\n      type: String,\n    },\n  },\n  computed: {\n    syncedName: {\n      get() {\n        return this.name\n      },\n      set(value) {\n        this.$emit('update:name', value)\n      },\n    },\n  },\n}\n```\n\n[`@PropSync`](#PropSync) works like [`@Prop`](#Prop) besides the fact that it takes the propName as an argument of the decorator, and also creates a computed getter and setter behind the scenes. This way you can interface with the property as if it was a regular data property whilst making it as easy as appending the `.sync` modifier in the parent component.\n\n### \u003ca id=\"Model\"\u003e\u003c/a\u003e `@Model(event?: string, options: (PropOptions | Constructor[] | Constructor) = {})` decorator\n\n```ts\nimport { Vue, Component, Model } from 'vue-property-decorator'\n\n@Component\nexport default class YourComponent extends Vue {\n  @Model('change', { type: Boolean }) readonly checked!: boolean\n}\n```\n\nis equivalent to\n\n```js\nexport default {\n  model: {\n    prop: 'checked',\n    event: 'change',\n  },\n  props: {\n    checked: {\n      type: Boolean,\n    },\n  },\n}\n```\n\n`@Model` property can also set `type` property from its type definition via `reflect-metadata` .\n\n### \u003ca id=\"ModelSync\"\u003e\u003c/a\u003e `@ModelSync(propName: string, event?: string, options: (PropOptions | Constructor[] | Constructor) = {})` decorator\n\n```ts\nimport { Vue, Component, ModelSync } from 'vue-property-decorator'\n\n@Component\nexport default class YourComponent extends Vue {\n  @ModelSync('checked', 'change', { type: Boolean })\n  readonly checkedValue!: boolean\n}\n```\n\nis equivalent to\n\n```js\nexport default {\n  model: {\n    prop: 'checked',\n    event: 'change',\n  },\n  props: {\n    checked: {\n      type: Boolean,\n    },\n  },\n  computed: {\n    checkedValue: {\n      get() {\n        return this.checked\n      },\n      set(value) {\n        this.$emit('change', value)\n      },\n    },\n  },\n}\n```\n\n`@ModelSync` property can also set `type` property from its type definition via `reflect-metadata` .\n\n### \u003ca id=\"Watch\"\u003e\u003c/a\u003e `@Watch(path: string, options: WatchOptions = {})` decorator\n\n```ts\nimport { Vue, Component, Watch } from 'vue-property-decorator'\n\n@Component\nexport default class YourComponent extends Vue {\n  @Watch('child')\n  onChildChanged(val: string, oldVal: string) {}\n\n  @Watch('person', { immediate: true, deep: true })\n  onPersonChanged1(val: Person, oldVal: Person) {}\n\n  @Watch('person')\n  onPersonChanged2(val: Person, oldVal: Person) {}\n\n  @Watch('person')\n  @Watch('child')\n  onPersonAndChildChanged() {}\n}\n```\n\nis equivalent to\n\n```js\nexport default {\n  watch: {\n    child: [\n      {\n        handler: 'onChildChanged',\n        immediate: false,\n        deep: false,\n      },\n      {\n        handler: 'onPersonAndChildChanged',\n        immediate: false,\n        deep: false,\n      },\n    ],\n    person: [\n      {\n        handler: 'onPersonChanged1',\n        immediate: true,\n        deep: true,\n      },\n      {\n        handler: 'onPersonChanged2',\n        immediate: false,\n        deep: false,\n      },\n      {\n        handler: 'onPersonAndChildChanged',\n        immediate: false,\n        deep: false,\n      },\n    ],\n  },\n  methods: {\n    onChildChanged(val, oldVal) {},\n    onPersonChanged1(val, oldVal) {},\n    onPersonChanged2(val, oldVal) {},\n    onPersonAndChildChanged() {},\n  },\n}\n```\n\n### \u003ca id=\"Provide\"\u003e\u003c/a\u003e `@Provide(key?: string | symbol)` / `@Inject(options?: { from?: InjectKey, default?: any } | InjectKey)` decorator\n\n```ts\nimport { Component, Inject, Provide, Vue } from 'vue-property-decorator'\n\nconst symbol = Symbol('baz')\n\n@Component\nexport class MyComponent extends Vue {\n  @Inject() readonly foo!: string\n  @Inject('bar') readonly bar!: string\n  @Inject({ from: 'optional', default: 'default' }) readonly optional!: string\n  @Inject(symbol) readonly baz!: string\n\n  @Provide() foo = 'foo'\n  @Provide('bar') baz = 'bar'\n}\n```\n\nis equivalent to\n\n```js\nconst symbol = Symbol('baz')\n\nexport const MyComponent = Vue.extend({\n  inject: {\n    foo: 'foo',\n    bar: 'bar',\n    optional: { from: 'optional', default: 'default' },\n    baz: symbol,\n  },\n  data() {\n    return {\n      foo: 'foo',\n      baz: 'bar',\n    }\n  },\n  provide() {\n    return {\n      foo: this.foo,\n      bar: this.baz,\n    }\n  },\n})\n```\n\n### \u003ca id=\"ProvideReactive\"\u003e\u003c/a\u003e `@ProvideReactive(key?: string | symbol)` / `@InjectReactive(options?: { from?: InjectKey, default?: any } | InjectKey)` decorator\n\nThese decorators are reactive version of `@Provide` and `@Inject`. If a provided value is modified by parent component, then the child component can catch this modification.\n\n```ts\nconst key = Symbol()\n@Component\nclass ParentComponent extends Vue {\n  @ProvideReactive() one = 'value'\n  @ProvideReactive(key) two = 'value'\n}\n\n@Component\nclass ChildComponent extends Vue {\n  @InjectReactive() one!: string\n  @InjectReactive(key) two!: string\n}\n```\n\n### \u003ca id=\"Emit\"\u003e\u003c/a\u003e `@Emit(event?: string)` decorator\n\nThe functions decorated by `@Emit` `$emit` their return value followed by their original arguments. If the return value is a promise, it is resolved before being emitted.\n\nIf the name of the event is not supplied via the `event` argument, the function name is used instead. In that case, the camelCase name will be converted to kebab-case.\n\n```ts\nimport { Vue, Component, Emit } from 'vue-property-decorator'\n\n@Component\nexport default class YourComponent extends Vue {\n  count = 0\n\n  @Emit()\n  addToCount(n: number) {\n    this.count += n\n  }\n\n  @Emit('reset')\n  resetCount() {\n    this.count = 0\n  }\n\n  @Emit()\n  returnValue() {\n    return 10\n  }\n\n  @Emit()\n  onInputChange(e) {\n    return e.target.value\n  }\n\n  @Emit()\n  promise() {\n    return new Promise((resolve) =\u003e {\n      setTimeout(() =\u003e {\n        resolve(20)\n      }, 0)\n    })\n  }\n}\n```\n\nis equivalent to\n\n```js\nexport default {\n  data() {\n    return {\n      count: 0,\n    }\n  },\n  methods: {\n    addToCount(n) {\n      this.count += n\n      this.$emit('add-to-count', n)\n    },\n    resetCount() {\n      this.count = 0\n      this.$emit('reset')\n    },\n    returnValue() {\n      this.$emit('return-value', 10)\n    },\n    onInputChange(e) {\n      this.$emit('on-input-change', e.target.value, e)\n    },\n    promise() {\n      const promise = new Promise((resolve) =\u003e {\n        setTimeout(() =\u003e {\n          resolve(20)\n        }, 0)\n      })\n\n      promise.then((value) =\u003e {\n        this.$emit('promise', value)\n      })\n    },\n  },\n}\n```\n\n### \u003ca id=\"Ref\"\u003e\u003c/a\u003e `@Ref(refKey?: string)` decorator\n\n```ts\nimport { Vue, Component, Ref } from 'vue-property-decorator'\n\nimport AnotherComponent from '@/path/to/another-component.vue'\n\n@Component\nexport default class YourComponent extends Vue {\n  @Ref() readonly anotherComponent!: AnotherComponent\n  @Ref('aButton') readonly button!: HTMLButtonElement\n}\n```\n\nis equivalent to\n\n```js\nexport default {\n  computed() {\n    anotherComponent: {\n      cache: false,\n      get() {\n        return this.$refs.anotherComponent as AnotherComponent\n      }\n    },\n    button: {\n      cache: false,\n      get() {\n        return this.$refs.aButton as HTMLButtonElement\n      }\n    }\n  }\n}\n```\n\n### \u003ca id=\"VModel\"\u003e\u003c/a\u003e `@VModel(propsArgs?: PropOptions)` decorator\n\n```ts\nimport { Vue, Component, VModel } from 'vue-property-decorator'\n\n@Component\nexport default class YourComponent extends Vue {\n  @VModel({ type: String }) name!: string\n}\n```\n\nis equivalent to\n\n```js\nexport default {\n  props: {\n    value: {\n      type: String,\n    },\n  },\n  computed: {\n    name: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      },\n    },\n  },\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaorun343%2Fvue-property-decorator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkaorun343%2Fvue-property-decorator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaorun343%2Fvue-property-decorator/lists"}