In Vue using Typescript, how would I go about defining a local data property that utilizes a prop as its initial value?

When passing a prop to a child component in Vue, the documentation states:

The parent component updates will refresh all props in the child component with the latest value. Avoid mutating a prop inside a child component as Vue will warn you in the console.

Use the prop to pass an initial value; then have the child component treat it as a local data property. Define a local data property using the prop's initial value:

props: ['initialCounter'],
data: function () {
  return {
    counter: this.initialCounter
  }
}

We are working with Typescript. The syntax for defining a local data property is as follows (from my understanding):

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

@Component
export default class App extends Vue {
  // Data property
  myDataProperty: string;
</script>

The syntax for a prop is as follows:

@Component
export default class App extends Vue {
  // Making "exampleProperty" a component prop with the default value of 'Example'
  @Prop({default: 'Example'})
  exampleProperty: string
}

Thus, we followed the documentation and ended up with:

parentComponent.vue

<template>
  <childComponent testProperty='test' />
</template>

childComponent.vue

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

@Component
export default class childComponent extends Vue {
  @Prop(
    {
      default: 'notTest',
      validator: (component) => {
        return [
          'notTest',
          'test',
        ].indexOf(component) > -1;
      },
    },
  )
  testProperty!: string;
  testProperty = this.testProperty;
</script>

This resulted in an error `Duplicate identifier testProperty` as expected. Therefore, we tried:

...
      testProperty!: this.testProperty;
...

which led to the following error message:

Duplicate identifier 'testProperty'. Property 'testProperty' has no initializer and is not definitely assigned in the constructor. Subsequent property declarations must have the same type. Property 'testProperty' must be of type 'this', but here has type 'any'.

Consequently, I decided to try the "vue-class-component" decorator.

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

@Component({
  data: function(){
    return {
      testProperty: this.testProperty,
    }
  }
})
export default class childComponent extends Vue {
  @Prop(
    {
      default: 'notTest',
      validator: (component) => {
        return [
          'notTest',
          'test',
        ].indexOf(component) > -1;
      },
    },
  )
  testProperty!: string;
  testProperty = this.testProperty;
</script>

This resulted in the error

Property 'testProperty' does not exist on type 'Vue'.

I intend to do

this.testProperty = 'newProperty'
in a handler at some point, but cannot due to directly modifying a prop.

How can I define a local data property that uses a prop as its initial value in Typescript?

EDIT:

If I simply define the prop without attempting to define a local data property using it as the initial value, and then execute

this.testProperty = 'test'

in a handler, Chrome console displays this error:

vue.runtime.esm.js[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "testProperty"

Answer №1

In a nutshell, the issue you're encountering stems from already defining this.testProperty as a prop. Utilizing testProperty = this.testProperty creates a circular reference. Simply using the @Prop decorator handles mapping the attribute in the template to the variable.

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

@Component
export default class childComponent extends Vue {
  @Prop(
    {
      default: 'notTest',
      validator: (component) => {
        return [
          'notTest',
          'test',
        ].indexOf(component) > -1;
      },
    },
  )
  testProperty!: string;

  // Map prop to local data property
  testPropertyLocal = this.testProperty;
</script>

Furthermore, keep in mind that VueJS properties should be kebab-case in templates and camelCase in JS. So, make sure to adjust your child component reference to:

<template>
  <childComponent test-property='test' />
</template>

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

Updating a string in JavaScript by dynamically adding values from a JSON object

In my current function, I am making a request to fetch data and storing it as an object (OBJ). Afterwards, I make another request to get a new URL that requires me to update the URL with values from the stored data. The information saved in the object is ...

Changing the data type of an integer to a string within an Object

I'm working with two arrays of objects. I need to convert the data values in the first format from integers to strings, but I'm struggling to find a simple solution. Is there anyone who can provide assistance? https://i.sstatic.net/mzqWE.png If ...

Is there a way to access the value or key of a JSON property in an Angular template for rendering purposes?

Having trouble displaying the JSON values of certain properties on screen. Utilizing Angular Material table to showcase my JSON response. The code snippet below is responsible for rendering the JSON data: <mat-card-content class="dashboard-card-cont ...

The issue with ui-router failing to render the template in MVC5

I'm having trouble setting up a basic Angular UI-Router configuration. My goal right now is to have a hardcoded template render properly, and then work on loading an external .html file. My project is using MVC5, so I'll provide the necessary fi ...

What steps can be taken to ensure that the v-model input is not updated?

Typically, when a user enters a value in an input field, it automatically updates a model. However, I am looking to temporarily prevent this automatic update. In my application, I have a canvas where users can draw grids by entering lengths and widths in i ...

Retrieve the AngularJS scope object by using an alternate scope object as the identifier

As I loop through an array of person objects using ng-repeat, imagine the array looks something like this: [{ "display_name": "John Smith", "status": "part-time", "bio": "I am a person. I do people stuff.", }, { "display_name": "Jane Doe", "stat ...

Uncovering the xpath of an element within an iframe using QTP

When attempting to set a value in the <input type="file" name="file007"> element using QTP, I encountered an issue. The element is located within an iframe, making it inaccessible through xpath on the page. <iframe id="file_007" src="javascript:& ...

What are some ways to sort through JSON data efficiently?

I am in need of filtering JSON data based on specific parameters. When using the GET method at http://localhost:5000/api/car?bodyTypeId=2, I expect to receive only JSON objects with bodyTypeId equal to 2. However, all objects are being returned: [ { ...

Conceal element when unchecked

There is a checkbox pre-selected labeled "Use profile address" with the address displayed below. If the customer unchecks the checkbox, the address that was shown before will disappear and a new input field for adding a different address will appear. I a ...

npm ERROR: Unable to install the package named "<packageName>" because it conflicts with an existing package of the same name

Currently, I am attempting to incorporate the jsonfile package into my project. However, I am encountering a couple of errors: An issue arises when attempting to install a package with the same name as another package within the same directory. (Despite ...

Setting a variable based on the stage of its deployment in a DevOps environment: What you need to know

Is there a way I can easily update a variable in a React app based on the stage of an Azure DevOps release pipeline? For instance, if I have dev, QA, and production stages set up, and I want to change the client ID in the auth configuration for each envi ...

React-modal triggers the file-explorer upon exiting the dropzone

Within my project, I have implemented a button that triggers a modal to appear on mouse-over. This button is nested inside a dropzone element. https://i.sstatic.net/95dxy.png The issue arises when I exit the modal by clicking (not exiting with the escape ...

Upon transitioning from Angular 5 to Angular 6, a noticeable issue arises: The existing document lacks a required doctype

I recently updated my project from Angular 5 to Angular 6. Post-upgrade, everything compiles without errors. However, when I try to access the website, all I see is a blank screen. Upon inspecting the console, I came across the following error message: Th ...

Unveiling the Magic: Displaying Quill's raw HTML in Vue.js

Within my Vue.js app, I am utilizing the Quill editor to generate raw HTML content that is saved directly to the database without any cleaning. When fetching this content from the backend, the text and styling are displayed correctly (colors, bolding, etc. ...

Using an AJAX request to edit a record directly without the need for a

When updating a record, I typically utilize CRUD operations and a store setup similar to the following: storeId: 'storeId', model: 'model', pageSize: 10, autoLoad: true, proxy: { typ ...

When the enter key is pressed in a contenteditable div, line breaks are disregarded

Is there a way to ensure that when the return key is pressed to start a new line for a post, the output actually starts on a new line? I've been having trouble with this and would like to know the most common solution. Check out the demo below for te ...

Save a newly uploaded image to Github utilizing NodeJS and the Github API

Struggling to upload an image to my Github repo using NodeJS and Github API has been a challenge for me. I have managed to create the SHA, Commit Tree, and all necessary steps, but the final hurdle is passing the image to the API and saving it as an actual ...

How can I declare CSS variables in Next.js components' module.css just like in global CSS?

When writing CSS in our global file, we often define variables and styles like this: :root{ --orange:#e67e22; --black:#333; --light-color:#777; --border:.1rem solid rgba(0,0,0,.2); --box-shadow:0 .5rem 1rem rgba(0,0,0,.1); } *{ mar ...

Extracting information from a Weather API and sharing it on Twitter

Can anyone help me troubleshoot my Twitter bot setup for tweeting out city temperatures? I attempted switching to a different API, but nothing seems to be resolving the issue. console.log('initiating twitter bot...') var Twit = require('t ...

Export interface for material-ui wrapper to cast any type in TypeScript (React)

I work with React using TypeScript. Recently, I encountered an issue with exporting. I'm creating an interface that encapsulates components from Material-ui. Here is a simplified example: Wrapping.tsx import { default as Component, ComponentProps ...