Incorporate a form component in Vue2, utilizing an input type of textarea to both display and edit data without the need to manipulate props

Embarking on building an MVP for the first time in web development. Leveraging Vue2 and Firebase, progress has been smooth up until now.

However, a roadblock has emerged that I am unable to navigate solo. Though the concept is clear in my mind, translating it into code has proven elusive. Seeking assistance from the community to unravel my thoughts, as I find myself tangled in confusion and frustration :D

Let's assess the current situation:

Child Component Having constructed a child component comprising a form with three text areas, let's examine one snippet for simplicity.

<template>
  <div class="wrap">
    <form class="form">
    
      <p class="label">Headline</p>
      <textarea rows="2" 
      v-model="propHeadline" 
      :readonly="readonly">
      </textarea>
      
      // To switch between read and edit
      <button
        v-if="readonly"
        @click.prevent="togglemode()">
        edit
      </button>
      <button
        v-else
        type="submit"
        @click.prevent="togglemode(), updatePost()"
      >
        save
      </button>
    </form>
  </div>
</template>

<script>
export default {
name: 'PostComponent',
  data() {
    return {
      readonly: true
    }
  },

  props: {
    propHeadline: {
      type: String,
      required: true
    }
  },
  
  methods: {
    togglemode() {
      if (this.readonly) {
        this.readonly = false
      } else {
        this.readonly = true
      }
    },
    updatePost() {
      // updates it to the API - that works
    }
  }
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
And the parent component:

<template>
  <div class="wrap">
      <PostComponent
        v-for="post in posts"
        :key="post.id"
        :knugHeadline="post.headline"
      />
  </div>
</template>

<script>
import PostComponent from '@/components/PostComponent.vue'

export default {
  components: { PostComponent },
  data() {
    return {
      posts: []
    }
  },
  created() {
    // Fetches all posts from DB and populates them in array "posts"
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

Current Status Seemingly, everything functions as intended. Posts are displayed effectively, and editing followed by saving modifications reflects seamlessly onto Firebase - impressive!

Problem / Error Message An error message surfaces, stating:

[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.

The directive suggests employing a computed property linked to the prop's value. How can this objective be accomplished?

Solution Approach It appears imperative to harness a computed getter to retrieve the prop value - any guidance on implementing this aspect would be greatly appreciated.

Furthermore, utilizing the setter to dispatch an event to the parent for updating the value so that the prop conveys the updated information back down - insights on achieving this are welcomed.

In my quest for resolution, online resources have offered fragmented solutions, painting a picture of harmonious families exchanging small bundles of data...

Your insight on navigating this challenge would be met with immense gratitude! :)

Many thanks in advance!

Answer №1

The reason for this error message is due to the v-model on the textarea element that mutates the prop, which is not allowed in Vue.js:

<textarea rows="2" 
  v-model="propHeadline" 
  :readonly="readonly">
  </textarea>

To resolve this issue, you can utilize the created() lifecycle hook to assign the value of propHeadline to a data property:

<script>
export default {
name: 'PostComponent',
  data() {
    return {
      readonly: true,
      headline: ""
    }
  },

  props: {
    propHeadline: {
      type: String,
      required: true
    }
  },
  
  created() {
     this.headline = this.propHeadline
  }
}
</script>

Then, update the v-model attribute to use the new variable on your textarea:

<textarea rows="2" 
  v-model="headline" 
  :readonly="readonly">
  </textarea>

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

Is there a way to retrieve the value of a dropped file in a file input using jQuery?

Can the data from a dropped file be set in a file upload input field? Or does a dropped file need to be instantly uploaded to the server? Here is an example code snippet: <input type="file" id="drop-box" /> $("#drop-box").on('drop', fun ...

Encountering a problem with serializing forms using jQuery

Currently, I am working on form serialization in order to send the file name to the server. However, I have encountered an issue where the serialization values are empty and I am expecting the file name to be included. Within my form, there is an HTML fil ...

Issue with dynamic form JavaScript functionality after removing curly braces { } from a select tag in Rails

In my Rails form, there is a gender field defined as follows: <%= f.select :gender, ["Male","Female"],{class: "gender"} %> I also tried adding an onclick event like this: <%= f.select :gender, ["Male","Female"],{class: "gender"},onclick: "categ ...

Finding elements in an array based on a specific string contained within a property

I am currently working on filtering JSON data to specifically search for job roles that begin with a particular string. The structure of the JSON is as follows : "periods": [ { "periodName": "Week1", "teamName": "Tango", ...

The middleware is causing disruptions in the configuration of redis and express

I've recently started using Redis and I'm facing an issue with my middleware 'cache' function that seems to be causing problems in my code. Everything works fine without it, the data displays correctly in the browser, and when I check f ...

What causes the reflection of JavaScript variables when there is a change in ng-model?

By declaring the object globally and assigning it during an HTTP call when the Angular controller loads, I am able to update the values of this object in the Angular scope variables and access them through ng-models. When a button is clicked and one of the ...

Wrapper component utilizing Vue.js with the beforeDestroy hook

For a wrapper component I'm working on, I need to ensure that Vuex is cleared when the component is closed. This component is registered in a menu, and the parent component is the default main page displayed when the page loads. The goal is to retrie ...

What could be causing the issue with the Vuetify autocomplete not displaying data within the component?

I'm facing an issue while creating a form using Vue.js & Vuetify. The autocomplete box is not displaying the list of schools that I have included as an array in the data function within the component. Instead, I'm getting the error message below ...

KnexJS raw query yielding unexpected results

I need help with the following issue: SET @count = 0; UPDATE table SET table.id = @count:= @count + 1 WHERE table.name = "name"; When I run this query through tools like Jetbrains Datagrip, it works fine. However, when I use Knex to execute it as a raw q ...

Issue with Chrome's webkit causing images to display incorrectly in slideshow

After researching the issue with webkit browsers and images, I came across a problem that I haven't been able to find a solution for yet. I developed a slideshow using jQuery that arranges images in a row and uses a mask element (with overflow: hidde ...

Using the Rails framework, a basic "remote: true" request does not produce a JavaScript response

In my Rails app, I have set up an iframe to display static HTML files from the same domain. Inside the iframe, I added a link with the remote attribute in hopes of making an in-place AJAX call to create a new nested resource. Here is the code snippet: --- ...

What is the best way to convert all the values from a dropdown list into Million or Billion using JavaScript?

Is there a way to convert the output numbers on the dropdown generated by this code into abbreviated formats, like in the examples below? (Example 1: If the output number is 1000000, I want it to show as 1M (million). Example 2: If the output number is 100 ...

What is the best way to display individual progress bars for each file uploaded using ajax?

Firstly, I want to express my gratitude for taking the time to read this. Secondly, I kindly ask you to revisit the title... I am not seeking assistance with a single progress bar as there is ample documentation available online for that. Instead, I am in ...

The "settings" injection was not located. The Vue composition API is encountering problems with providing and injecting

I'm encountering an issue while attempting to pass a reactive object using Vue's provide and inject method. I keep receiving the warning message [Vue warn]: injection "settings" not found. and when I try to log out settings, it shows up as undefi ...

Clicking on the FLOT graph will trigger an expansion of the visualization

Currently, I am utilizing the flot library for data plotting functionality. Flot utilizes the height and width properties of a div to create the plotted data, as shown below: <div id="graph" style="width: 300px; height: 300px;"></div> I am in ...

Build a JavaScript image carousel featuring custom text for each image

I recently completed a tutorial on creating JavaScript image sliders. I have successfully added a text box to display on each image, but now I need the text to be specific for each individual image. The images are sourced from an img folder and are labeled ...

Switching an application from Angular 5 to Angular 8 can lead to unexpected styling problems

My current project is based on Angular version 5.2, but we recently decided to upgrade it to Angular 8 along with updating the Angular CLI. After completing the necessary code refactoring for Angular 8, the application builds successfully without any error ...

Having trouble establishing a connection to SQL Server with tedious in Node.js

Trying to connect to the SQL Server "SQL.SCHOOL.EDU\STUDENTSQLSERVER,4500" from my school has been a real challenge for me using tedious. I am currently working on setting up a connection between my express back end and react front end. For now, I am ...

Utilizing a JSON object named "shop" to populate a grid within a fresh ExtJS window

Similar to this Stack Overflow question, my issue involves loading JSON data into a new window. I want the structure of the new window to be like this example. The challenge is combining the solutions for reading JSON and creating a grid in a new window, ...

The function is not able to fetch the value from the Amazon S3 file, however, it is printed

Despite troubleshooting methods such as declaring the variable outside the function and attempting to return it from the function, the below code is still not returning the Amazon S3 content. It seems to work when logging the data value on the console. ...