Use Vue 2 with TypeScript to prevent directly changing Props in a class-based component using vue-property-decorator

Is there a way to declare a Prop using vue-property-decorator in a class-based component without the need to initialize it?

Currently, I'm facing a dilemma:

  1. If I don't provide an initializer, TypeScript throws an error during compilation:

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

  1. On the other hand, if I do initialize the property, VueJS issues a warning at runtime:

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

The current solution works, but dealing with the warning is bothersome and leaves me wondering if there's a better approach:

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"   
}

Answer №1

If you do not set a value for a property during the construction phase, it is important to explicitly state that it may be undefined:

parentData: Client | undefined;

To assign a default value for a member decorated with @Prop, make sure to use the decorator's default parameter:

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

Alternatively, although not recommended, you can include

"strictPropertyInitialization": false
in your TypeScript compiler options.

Update 1:

The best solution for such scenarios is to utilize the definite assignment assertion modifiers, which were introduced in TypeScript 2.7. By combining this with default initialization using the Prop decorator, you should be able to solve the issue:

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

Answer №2

Perhaps I am a tad tardy, but if you're utilizing Vue with Typescript, it might be beneficial to opt for PropSync over Prop from the vue-property-decorator.

For instance, instead of:

@Prop() propArrayName!: type[];

You could use:

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

This approach helps prevent mutation using Prop() and computes the prop instead... further details can be found here:

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The error message "SyntaxError: Cannot use import statement outside a module" popped up while working with discord.js, typescript, heroku

// Necessary imports for running the discord bot smoothly import DiscordJS, { TextChannel, Intents, Message, Channel, NewsChannel, ThreadChannel, DiscordAPIError } from 'discord.js' type guildTextBasedChannel = TextChannel | NewsChannel | ThreadC ...

Styling your Vuetify V-data-table with CSS

Struggling to add extra spacing between table rows, despite inspecting the page and verifying that my styles are not being overridden. Have read other Vuetify posts on applying CSS but still no luck. Any suggestions for why I can't style my table as d ...

Cleve js does not include delimiters in its date output

In my Vue.js project, I decided to implement a date input field using cleave.js. After passing the following options: options="{date: true, delimiter: '/', datePattern: ['m', 'd', 'Y']}" I encountered an issue wh ...

Creating a new element in the DOM when a button is clicked using Angular 2+

Greetings! I am currently in the process of learning how to manipulate the DOM using Angular 2+ and my goal is to incorporate an Input field with type email when the click event is activated. Despite conducting some research via Google, I have been unable ...

Get rid of the TypeScript error in the specified function

I am currently working on implementing a "Clear" button for a select element that will reset the value to its default state. Here is a snippet of my code: const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => { onChange( ...

Uploading images with Laravel and VueJS

I am having trouble with Vuejs image upload. My backend is Laravel, but for some reason the images are not being sent to the Controller. <form method="POST" class="form-horizontal" role="form" v-on:submit.prevent="updateProduct(editProduct.id)" en ...

Introducing the concept of type-specific name inclusion

I am currently developing my Angular app using TypeScript with the goal of preventing redundancy through some form of generic handling. Here is where I am starting: class BaseProvider { api_url = 'http://localhost:80/api/FILL_OUT_PATH/:id&apo ...

Transform a standard array of strings into a union string literal in TypeScript

I'm currently developing a module where users can specify a list of "allowable types" to be utilized in other functions. However, I'm encountering challenges implementing this feature effectively with TypeScript: function initializeModule<T ex ...

What steps can be taken to display the English translation if the desired translation is not found in the designated language file?

My setup includes two different locales: ru and en. If a translation is not found in the selected language file, how can I display the English version? Here are my current internationalization settings: i18n: { defaultLocale: 'en', f ...

Removing a child component in Vue along with its state

Is there a way to properly delete a child component in VueJs without causing unwanted side effects? I have tried using this.rows.splice(index, 1) but it always ends up removing the last component from this.$children and saving the internal state in compon ...

Iterating variables in Vue.js is reminiscent of the process in AngularJS

When working on my application using vue.js, I am interested in finding the last repeated element within a v-for directive. I understand that in angularjs, there is a similar concept using the $last loop variable in its ngRepeat directive: <div ng-repe ...

Tips for getting the sum of an array using the reduce method in Vue.js and returning the result array

As someone new to JavaScript, I apologize if my description of the issue is not clear. It's challenging for me to explain the problem I am facing. I have a computed function where I use the reduce method to iterate over my objects, perform calculatio ...

When utilizing destructuring in React.js with TypeScript, incorrect prop values are not being alerted as expected

I recently started using TypeScript and I have been enjoying it so far. However, I came across an issue today that I couldn't solve. Imagine a scenario where a parent component A passes a function that expects a numeric value to the child component B ...

Leveraging Vue js components while utilizing it from a content delivery network (CDN

I'm attempting to utilize the ButtonCounter component as a demonstration (source: https://vuejs.org/guide/essentials/component-basics.html#defining-a-component), but I am facing difficulties in getting it to function properly. I am utilizing Vue.js 3 ...

Issue with Vue Loading Overlay Component functionality in nuxt2 .0

I've integrated the vue-loading-overlay plugin into my project. plugins/vueloadingoverlaylibrary.js import Vue from 'vue'; import Loading from 'vue-loading-overlay'; // import 'vue-loading-overlay/dist/vue-loading.css'; ...

Tips for adding an extensive collection of fixed attributes to a function using Typescript

I am attempting to write a function that includes a lengthy list of static strings attached as properties, all returning the property as a string value: const arr = ["a", "b", "c"]; // there are around 140 items in the actual list const f = (tag: strin ...

What is the best way to retrieve an object within a class?

Exploring a Class Structure: export class LayerEditor { public layerManager: LayerManager; public commandManager: CommandManager; public tools: EditorTools; constructor() { this.commandManager = new CommandManager(); this.lay ...

Creating an Http interceptor in Ionic 3 and Angular 4 to display a loading indicator for every API request

One of my current challenges involves creating a custom HTTP interceptor to manage loading and other additional functions efficiently. Manually handling loading for each request has led to a considerable increase in code. The issue at hand: The loader is ...

The Vue 3 page does not allow scrolling unless the page is refreshed

I am encountering an issue with my vue3 web app. Whenever I attempt to navigate to a page using <router-link to ="/Dashboard"/> Here is the code for Dashboard.vue: <template> <div class="enquiry"> <div class= ...

There has been a mistake: The module '.... ode_modules erser-webpack-plugindistindex.js' cannot be found. Please ensure that the package.json file contains a correct "main" entry

After setting up Vue.js and executing npm run serve, I encountered the following error: PS C:\Amit\Demo\VUEDemo\myvue> npm run serve > <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="98f5e1eeedfdd8a8b6 ...