3
votes

I want to be able to declare my Prop, using vue-property-decorator, in a class based component, without having to initialize the property.

I'm backed into a corner:

  1. If I don't initialize, TypeScript doesnt compile:

"TS2564 (TS) Property 'parentData' has no initializer and is not definitely assigned in the constructor."

  1. If I do initialize, VueJS throws a warning at runtime:

"Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders."

What I have below works, but the warning is quite annoying and also makes me think there is a better way to do it:

import Vue from 'vue';
import { Component, Prop } from 'vue-property-decorator';
import { Client } from '../../../../domainmodels/client';

@Component({})
    export default class SearchLocationsComponent extends Vue {

         @Prop() 
         parentData: Client = new Client();

    }


My dependencies:   
"devDependencies": {
    "@types/webpack-env": "^1.13.0",
    "aspnet-webpack": "^2.0.1",
    "awesome-typescript-loader": "^3.0.0",
    "css-loader": "^0.25.0",
    "event-source-polyfill": "^0.0.7",
    "extract-text-webpack-plugin": "^2.0.0-rc",
    "file-loader": "^0.9.0",
    "style-loader": "^0.13.1",
    "typescript": "^2.2.1",
    "url-loader": "^0.5.7",
    "vue": "^2.2.2",
    "vue-loader": "^11.1.4",
    "vue-property-decorator": "^5.0.1",
    "vue-router": "^2.3.0",
    "vue-template-compiler": "^2.2.2",
    "webpack": "^2.2.0",
    "webpack-cli": "^3.3.2",
    "webpack-hot-middleware": "^2.12.2"   
}
2

2 Answers

3
votes

If you are not initializing a property during the construction phase, you should explicitly indicate that it could be undefined:

parentData: Client | undefined;

For assigning default value for @Prop decorated member, you should use decorator's default parameter:

@Prop({ default: () => new Client}) 
parentData: Client | undefined;

Or, as not recommended option, you can add "strictPropertyInitialization": false to your typescript compiler options.

Update 1:

Most suitable workaround for such case is to use definite assignment assertion modifiers, introduced in typescript 2.7. Combining it with default Prop decorator initialization should do the trick:

@Prop({ default: () => new Client }) 
parentData!: Client;
1
votes

maybe I'm a little bit late, but if you are writing Vue in Typescript, you may want to use PropSync instead of Prop that vue-property-decorator provides.

So for example you have the following:

@Prop() propArrayName!: type[];

instead you can use:

@PropSync('propArrayName', { type: Array }) _localArrayVariable!: type[];

this way you avoid mutating Prop() but instead the prop is computed()... you can read more here:

https://github.com/kaorun343/vue-property-decorator#-propsyncpropname-string-options-propoptions--constructor--constructor---decorator