You can use property accessors to declare computed properties. See Vue Class Component. The getter will be triggered as soon as you type in the input.

For example:

<template>
    <div>
        <input type="text" name="Test Value" id="" v-model="text">

        <label>{{label}}</label>
    </div>

</template>

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

@Component({})
export default class About extends Vue {
    private text = "test";

    get label() {
        return this.text;
    }
}
</script>

Update for Vue Composition Api

<template>
  <div>
    <input type="text" name="Test Value" id v-model="text" />

    <label>{{label}}</label>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, computed } from "@vue/composition-api";

export default defineComponent({
  setup() {
    const text = ref("test");

    const label = computed(() => {
      return text.value;
    });

    return {
      text,
      label
    };
  }
});
</script>
Answer from Jeremy Walters on Stack Overflow
🌐
GitHub
github.com › kaorun343 › vue-property-decorator
GitHub - kaorun343/vue-property-decorator: Vue.js and Property Decorator · GitHub
February 7, 2024 - @PropSync works like @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. import { Vue, Component, Model } from 'vue-property-decorator' @Component export default class YourComponent extends Vue { @Model('change', { type: Boolean }) readonly checked!: boolean }
Starred by 5.5K users
Forked by 377 users
Languages   TypeScript 86.7% | JavaScript 13.3%
🌐
GitHub
github.com › kaorun343 › vue-property-decorator › issues › 85
Computed attributes · Issue #85 · kaorun343/vue-property-decorator
March 1, 2018 - Converting from getters / setters into computed properties is provided by vue-class-component.
Top answer
1 of 3
80

You can use property accessors to declare computed properties. See Vue Class Component. The getter will be triggered as soon as you type in the input.

For example:

<template>
    <div>
        <input type="text" name="Test Value" id="" v-model="text">

        <label>{{label}}</label>
    </div>

</template>

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

@Component({})
export default class About extends Vue {
    private text = "test";

    get label() {
        return this.text;
    }
}
</script>

Update for Vue Composition Api

<template>
  <div>
    <input type="text" name="Test Value" id v-model="text" />

    <label>{{label}}</label>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, computed } from "@vue/composition-api";

export default defineComponent({
  setup() {
    const text = ref("test");

    const label = computed(() => {
      return text.value;
    });

    return {
      text,
      label
    };
  }
});
</script>
2 of 3
23

Because of the circular nature of Vue’s declaration files, TypeScript may have difficulties inferring the types of certain methods. For this reason, you may need to annotate the return type on methods like render and those in computed.

import Vue, { VNode } from 'vue'

const Component = Vue.extend({
  data () {
    return {
      msg: 'Hello'
    }
  },
  methods: {
    // need annotation due to `this` in return type
    greet (): string {
      return this.msg + ' world'
    }
  },
  computed: {
    // need annotation
    greeting(): string {
      return this.greet() + '!'
    }
  },
  // `createElement` is inferred, but `render` needs return type
  render (createElement): VNode {
    return createElement('div', this.greeting)
  }
})

If you find type inference or member completion isn’t working, annotating certain methods may help address these problems. Using the --noImplicitAny option will help find many of these unannotated methods.

More Info

People also ask

What is vue-property-decorator?
property decorators for Vue Component. Visit Snyk Advisor to see a · full health score report · for vue-property-decorator, including popularity, security, maintenance · &amp; community analysis.
🌐
snyk.io
snyk.io › advisor › javascript packages › vue-property-decorator
vue-property-decorator - npm Package Health Analysis | Snyk
Is vue-property-decorator popular?
The npm package vue-property-decorator receives a total · of 331,224 weekly downloads. As · such, vue-property-decorator popularity was classified as · an · influential project. Visit the · popularity section · on Snyk Advisor to see the full health analysis.
🌐
snyk.io
snyk.io › advisor › javascript packages › vue-property-decorator
vue-property-decorator - npm Package Health Analysis | Snyk
Is vue-property-decorator safe to use?
The npm package vue-property-decorator was scanned for · known vulnerabilities and missing license, and no issues were · found. Thus the package was deemed as · safe to use. See the full · health analysis review.
🌐
snyk.io
snyk.io › advisor › javascript packages › vue-property-decorator
vue-property-decorator - npm Package Health Analysis | Snyk
🌐
npm
npmjs.com › package › vue-property-decorator
vue-property-decorator - npm
@PropSync works like @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. import { Vue, Component, Model } from 'vue-property-decorator' @Component ·
      » npm install vue-property-decorator
    
Published   Nov 20, 2020
Version   9.1.2
Author   kaorun343
🌐
LogRocket
blog.logrocket.com › home › define properties with vue property decorator and typescript
Define properties with Vue Property Decorator and TypeScript - LogRocket Blog
June 4, 2024 - To solve this issue, the Vue Class Component plugin uses ECMAScript decorators to pass statically typed values directly to components in Vue, making the compiler understand what is happening. In this article, you’ll learn how to define properties like data, methods, computed properties, props, and watchers directly on the class in Vue components by supporting TypeScript in Vue class-based components.
🌐
Vuejs
class-component.vuejs.org › guide › class-component.html
Class Component | Vue Class Component
<template> <input v-model="name"> </template> <script> import Vue from 'vue' import Component from 'vue-class-component' @Component export default class HelloWorld extends Vue { firstName = 'John' lastName = 'Doe' // Declared as computed property getter get name() { return this.firstName + ' ' + this.lastName } // Declared as computed property setter set name(value) { const splitted = value.split(' ') this.firstName = splitted[0] this.lastName = splitted[1] || '' } } </script>
🌐
Snyk
snyk.io › advisor › javascript packages › vue-property-decorator
vue-property-decorator - npm Package Health Analysis | Snyk
October 4, 2020 - Learn more about vue-property-decorator: package health score, popularity, security, maintenance, versions and more.
🌐
Kyounghwan01
kyounghwan01.github.io › blog › TS › Vue › grammer
vue-property-decorator 문법 | 기억보다 기록을
export default { data() { return { setterExample: null; } } computed: { test() { return "test"; }, getterSetter: { get() { return 'getter'; }, set(value) { this.setterExample = value; } } } }; class형 컴포넌트에서 쓰던 전형적인 getter, setter 형식을 따릅니다 · import { Components, Vue, Prop } from 'vue-property-decorator'; @Component export default class Home extend Vue { public setterExample!: string | null = null; get getterSetter() { return 'getter'; } set getterSetter(value) { this.setterExample = value; } } watch는 첫번째 인자로 감시할 값, 두번째 인자는 옵션을 지정합니다.
Find elsewhere
🌐
egghead.io
egghead.io › lessons › vue-js-use-properties-in-vue-components-using-prop-decorator-with-typescript
Use Properties in Vue Components Using @Prop Decorator with TypeScript | egghead.io
[00:42] We can fix that by creating another class, say hello component, and recreating the message property there. Now, it will stem from it. It stems from Vue. Then it does understand it. We still need to use that full message computed property into the HTML. [01:04] If we try this, we'll see that's working, but there is an easier way to do this by using decorators.
Published   June 9, 2017
🌐
DigitalOcean
digitalocean.com › community › tutorials › vuejs-typescript-class-components
How To Write Class-Based Components with Vue.js and TypeScript | DigitalOcean
March 16, 2021 - Through the use of the @Prop(config) decorator from vue-property-decorator, you can declare input properties in much the same way as data properties. Here is an example in TypeScript that takes a exampleProperty a component prop with the default value of 'Input Property': ... At this point, if you were to compile and observe your application in a browser, you would be presented with the message: Input Property. Computed ...
🌐
GitHub
github.com › kaorun343 › vue-property-decorator › issues › 173
How do you achieve nested computed variables if you are using namespaced modules in your vuex store? · Issue #173 · kaorun343/vue-property-decorator
February 12, 2019 - How do you achieve nested computed variables if you are using namespaced modules in your vuex store? As mentioned in this tutorial, computed properties are implemented in vue-property-decorator as ES6 getters: @Component export default c...
Top answer
1 of 3
7

TL:DR

I'm new in Vue (coming from React) but from what I understand the answer above is not wrong but it doesn't answer the question of how to use @Model decorator. Provide and Inject is an overkill for passing props from parent to child. The documentation is not clear, so I scratched my head a lot on this one. But remember that the package is referring to props. Hence @Prop, @PropSync and @Model should be at the child component. Here is what I did and it didn't throw out that horrible console error. Parent component:

<template>
  <div>
     <input type="text" v-model="modelText" />
    <Child 
      :modelText="modelText"
    />
  </div>
</template>

<script lang="ts">
import Component from 'vue-class-component';
import Vue from 'vue';
import Child from './Child.vue';

@Component({
  components: {
    Child,
  }
})
export default class Parent extends Vue {
  private modelText: string = 'model-text';
}
</script>

And for the child component:

<template>
    <div>
      @Model: {{modelText}}
    </div>
</template>

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

@Component({

})
export default class Child extends Vue {
  @Model('input', { type: String }) modelText!: string;
}
</script>
2 of 3
5

Since v. 9.1.2 view-property-decorator now supports the @VModel decorator.

Where

import { Vue, Component, VModel } from 'vue-property-decorator'

@Component
export default class CustomComponent extends Vue {
  @VModel() name!: string
}

will make it possible to use two-way-databinding with name inside the component and v-model="..." from the outside. Without the annoying warnings!

https://github.com/kaorun343/vue-property-decorator#-vmodelpropsargs-propoptions-decorator

🌐
Stack Overflow
stackoverflow.com › questions › tagged › vue-property-decorator
Newest 'vue-property-decorator' Questions - Stack Overflow
When I only use Jest with Vue project, I can't import subcomponent in component, if I do according to tips, also I cannot define private variable the reproduce project :jest-decorator-issue also can ... ... my stacks are Nuxtjs and Nuxt-property-decorator I've made a mixin to avoid repeating a method that method need a component ( Alert component ) so , I imported that component in mixin But i have error ...
🌐
egghead.io
egghead.io › lessons › vue-js-define-props-on-a-vue-class-with-vue-property-decorator
Define Props on a Vue Class with vue-property-decorator | egghead.io
vue-property-decorator allows you to define your properties directly on your class with a simple @Prop() decorator. This approach allows your classes to...
Published   December 13, 2017
🌐
GitHub
github.com › kaorun343 › vue-property-decorator › issues › 389
How to convert getter to computed property? · Issue #389 · kaorun343/vue-property-decorator
June 25, 2021 - Hi. I use vue + vuex + ts + nuxt + vue-property-decorator in my project. I have getter like this: public get polls(): PollData[] { return this.$store.getters[`polls/getPolls`]; } It will be transpiled to typical getter: get polls() { ret...
Top answer
1 of 4
18

We are using Vue 2 with a lot of components built on top of class based components using vue-class-component and vue-property-decorator.

Now we need to upgrade to Vue 3 for better performance and long time support.

To answer your questions:

  1. I did a lot of research and there is no plan to support class based components going forward from here. The two plugins from above are stuck at RC level for Vue 3. See: https://github.com/vuejs/vue-class-component/issues/406

  2. A library which is not maintained and/or properly tested with a new Version of Vue is never a good idea to use imo.

  3. Thats a question where there is no clear answer for.

You can try this strategy, maybe it works for you too:

We added the composition API and script setup via these plugins to our existing Vue 2 code base:

  • https://github.com/vuejs/composition-api
  • https://github.com/antfu/unplugin-vue2-script-setup

Update 22/07/10: Vue 2.7 (the last minor release) was released, there is no need for the plugins above when using this version: https://blog.vuejs.org/posts/vue-2-7-naruto.html

This allows us to use composition API + script setup and class based components simultaneously. So we are beginning to write new components with the new syntax and rewriting old code step by step. When we are done with this process, we are going to migrate to Vue 3 using the migration guide:

  • https://v3-migration.vuejs.org/

That is a lot of work and very annoying to do, as it takes a lot of time away from new features or bugfixes which are more important than dealing with this upgrade pain. But we hope going forward from here that Vue is going to me more stable in their decisions and how they want to continue forward.

I also agree with you saying that class based components are a more elegant way to do things than the composition API. It is also shorter and closer to backend programming languages. Its very sad to see this one go.

All the best Jakob

Update 23/04/14: Great new article on how one could continue using class based components: https://medium.com/@robert.helms1/vue-2-to-vue-3-with-class-components-cdd6530a2b2a

Further ressources:

Guide: https://levelup.gitconnected.com/from-vue-class-component-to-composition-api-ef3c3dd5fdda

More reasons why they drop it:

https://github.com/vuejs/rfcs/pull/17#issuecomment-494242121

https://github.com/vuejs/rfcs/blob/function-apis/active-rfcs/0000-function-api.md#type-issues-with-class-api

https://vuejs.org/guide/extras/composition-api-faq.html#better-type-inference

2 of 4
4

FWIW, despite the fact that I am really more a fan of using class based components, we made the decision to convert all our ±300 components to Options API. So at least we can upgrade to Vue@3 and Vite. Changing the complete codebase to Composition API (with <script setup>) is not worth it and potentially error prone. All new components will be written with <script setup> though.

Steps that we followed to get there:

  1. Make sure you are at [email protected]. This version includes backported features from vue@3, including Composition API and <script setup>. See their blog.
  2. Check and update all dependencies to be compatible with [email protected] (e.g. we make extensive use of AgGrid that needed to be at version 27).
  3. Gradually convert all class components to Options API via this package: https://www.npmjs.com/package/vue-declassify. (Only the @Emit decorator needs to be handled manually). cd into a directory that you want to convert and run this command: find . -name "*.vue" -exec vue-declassify {} \; to execute the converted on multiple vue files sequentially.

This process took us approximately 2 days to execute completely.

NB: Make sure that your codebase is thoroughly backed by unit and e2e tests prior starting this process .

🌐
GitHub
github.com › kaorun343 › vue-property-decorator › blob › master › src › decorators › PropSync.ts
vue-property-decorator/src/decorators/PropSync.ts at master · kaorun343/vue-property-decorator
February 7, 2024 - * @return PropertyDecorator | void · */ export function PropSync( propName: string, options: PropOptions | Constructor[] | Constructor = {}, ) { return (target: Vue, key: string) => { applyMetadata(options, target, key) createDecorator((componentOptions, k) => { ;(componentOptions.props || (componentOptions.props = {} as any))[ propName · ] = options · ;(componentOptions.computed || (componentOptions.computed = {}))[k] = { get() { return (this as any)[propName] }, set(this: Vue, value) { this.$emit(`update:${propName}`, value) }, } })(target, key) } }
Author   kaorun343
🌐
Snyk
snyk.io › advisor › vue-class-component › functions › vue-class-component.createdecorator
How to use the vue-class-component.createDecorator function in vue-class-component | Snyk
function makeDecorator(alias, namespace) { return createDecorator((componentOptions, key) => { let ns = namespace || componentOptions.namespace; if (!componentOptions.computed) { componentOptions.computed = {}; } componentOptions.computed[key] = ns !== undefined ? sync(`${ns}/${key}`) : sync(`${key}`); }); } kaorun343 / vue-property-decorator / src / vue-property-decorator.ts View on Github ·
🌐
UNPKG
app.unpkg.com › vue-property-decorator@9.1.1 › files › README.md
vue-property-decorator
It's **not** supported to define each `default` property like `@Prop() prop = 'default value'` . ### <a id="PropSync"></a> `@PropSync(propName: string, options: (PropOptions | Constructor[] | Constructor) = {})` decorator ```ts import { Vue, Component, PropSync } from 'vue-property-decorator' @Component export default class YourComponent extends Vue { @PropSync('name', { type: String }) syncedName!: string } ``` is equivalent to ```js export default { props: { name: { type: String, }, }, computed: { syncedName: { get() { return this.name }, set(value) { this.$emit('update:name', value) }, }, }, } ``` [`@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.
🌐
Npm
npm.io › package › vue-property-decorator
Vue-property-decorator NPM | npm.io
import { computed } from 'vue' const symbolKey = Symbol() export default { data() { return { foo: 'foo', baz: 'bar', nice: 'nice', age: 30, } }, provide() { return { foo: this.key, bar: this.baz, [symbolKey]: this.nice, age: computed(() => this.age), } }, } import { Vue, Inject } from 'vue-property-decorator' export class MyComponent extends Vue { @Inject() foo!: string @Inject({ from: 'bar' }) baz!: string @Inject({ default: '' }) nice!: string }