What is the best way to implement a multi-row form in Vue.js?

Form Structure:


    <card-wrapper
      v-for="(passenger, index) in form.passenger"
      :key="index"
      :icon="['fas', 'user']"
      :title="`Passenger ${index + 1}`"
      class="mb-5"
    >
      <validation-observer
        :ref="`passengerForm${index + 1}`"
        tag="div"
        class="row"
      >
        <b-col cols="12" class="mb-3">
          <b-row>
            <b-col lg="4" cols="12">
              <validation-provider
                v-slot="{ errors }"
                rules="required"
                name="First name"
                tag="div"
              >
                <form-text
                  id="first-name"
                  v-model="passenger.first_name"
                  :icon="['fas', 'user']"
                  :errors="errors[0]"
                  placeholder="First name"
                  tabindex="0"
                  class="mb-4"
                />
              </validation-provider>
            </b-col>

            <b-col lg="4" cols="12">
              <validation-provider
                v-slot="{ errors }"
                rules="required"
                name="Last name"
                tag="div"
              >
                <form-text
                  id="last-name"
                  v-model="passenger.last_name"
                  :icon="['fas', 'user']"
                  :errors="errors[0]"
                  placeholder="Last name"
                  tabindex="0"
                  class="mb-4"
                />
              </validation-provider>
            </b-col>
....

Form Data:


      form: {
        type: 'InvitationLetter',
        status: 'real',
        code: '',
        price: 18,
        gender: '',
        firstName: '',
        lastName: '',
        email: '',
        phone: '',
        destination1: '',
        destination2: '',
        social_media: [],
        options: [],
        passenger: [
          {
            gender: '',
            first_name: '',
            last_name: '',
            nationality: '',
            birth_date: '',
            passport_expiry_date: '',
            passport_number: '',
            travel_insurance: ''
          }
        ]
      }

The form functionality works fine until editing the data fetched from the server triggers the following error message:

[vuex] do not mutate vuex store state outside mutation handlers.

The page component fetches data like this:

pages/invitation-letter/_id.vue


  async fetch({ params, store }) {
    const PARAM = params.id
    if (PARAM) {
      await store.dispatch('invitationLetter/fetch', PARAM)
    }
  }

The form data is set in the form component as demonstrated below:


 computed: {
    ...mapGetters({
      result: 'invitationLetter/getData'
    }),
  created() {
    Object.keys(this.result).length !== 0 && this.setFormData()
  },
  methods: {
   setFormData() {
      this.count = this.result.passenger.length

      const NAME = this.result.name.split('-')
      const KEYS = Object.keys(this.form)

      KEYS.forEach((item) => {
        if (item !== 'firstName' && item !== 'lastName') {
          this.form[item] = this.result[item] ? this.result[item] : ''
        }

        ;[this.form.firstName, this.form.lastName] = [NAME[0], NAME[1]]
      })
    }
  }

While the form fields are populated correctly after fetching data from the server, any attempt to modify the data results in the same error message being displayed:

[vuex] do not mutate vuex store state outside mutation handlers.

This is how the form looks after fetching data from the server:

https://i.stack.imgur.com/b4GvW.png

Answer №1

It is advisable to avoid using the setFormData method as it may be unnecessary and could potentially cause errors. Instead, consider storing your form data in the store, retrieving it using a getter in the parent component where you utilize v-for, and updating its value in the store solely through mutations. Vue has built-in reactivity that will automatically update data in components.

For more information, refer to: Vuex getters Vue reactivity

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

My Angular custom libraries are having issues with the typing paths. Can anyone help me troubleshoot what I might be doing

After successfully creating my first custom Angular library using ng-packagr, I encountered an issue where the built library contained relative paths specific to my local machine. This posed a problem as these paths would not work for anyone else trying to ...

Is there a way to insert a row into a datatable without needing to perform an Ajax reload or using the

When using row.add(…) on a datatable, I encounter an issue where it refreshes via an ajax call when draw() is activated. This leads to the new row not being visible because the data is reloaded from the database. The UX flow behind this scenario is as f ...

Monitoring changes in input can be a crucial step in any data analysis

Is there a way to track changes in input using backbone? How it can be achieved in AngularJs: <div ng-controller="W3"> <input type="text" ng-model="val" > <p>{{val}}</p> </div> I would like the value of the in ...

NextJs manages the logic for processing requests both before and after they are handled

NextJs stands out from other frameworks due to its lack of support for filter chains, request pre-processing, and post-processing. Many node project developers or library creators may find these features essential for executing logic before and after API c ...

Leveraging Multiple MongoDB Databases in Meteor.js

Can 2 Meteor.Collections fetch data from separate MongoDB database servers? Dogs = Meteor.Collection('dogs') // mongodb://192.168.1.123:27017/dogs Cats = Meteor.Collection('cats') // mongodb://192.168.1.124:27017/cats ...

Mongoose makes sure that duplicate rows are not repeated in the database

I'm working with a basic mongoose schema definition below: const mongoose = require('mongoose'); const followSchema = new mongoose.Schema({ follower: { type: mongoose.Schema.Types.ObjectId, ref: 'User', ...

Variable type linked to interface content type

Is it possible to link two fields of an interface together? I have the following interface: export interface IContractKpi { type: 'shipmentVolumes' | 'transitTime' | 'invoices'; visible: boolean; content: IKpiContent; } ...

Building a Many-to-Many Relationship in Node.js Using Sequelize.js

As I utilize the sequelize node.js module to structure schema in Postgres SQL, I have defined two schemas for Project and my users. Project Schema module.exports = function(sequelize, DataTypes) { var project = sequelize.define('project', { ...

Is there a way to export a specific portion of a destructuring assignment?

const { a, ...rest } = { a: 1, b: 2, c: 3 }; If I want to export only the rest object in TypeScript, how can I achieve that? ...

Why is my Heroku deployment not working properly?

I encountered an issue during the deployment of my application. I developed a PWA locally using Laravel and vueJs, and everything was working fine. My MySQL database has 5 migrations and seeders set up. Now, I am trying to deploy it on Heroku following th ...

What is the best method to retrieve a secure httponly cookie in a Next.js application?

Our next JS application is making a request to The backend team has configured the response cookie as a secure HttpOnly cookie. const session = await ( await fetch( `https://demo.com/auth/session`, requestOptions )).json(); console.log(&qu ...

Is it best to stick with a static page size, or

While I typically design my webpages dynamically by determining the screen size and creating divs accordingly, I'm curious about the advantages of using a 'static' sizing approach (such as using pixels). Any insights on this contrasting meth ...

Store Form Input as JSON Data File

Seeking advice on the optimal method to save submitted form data to a separate file called data.json, for future reference. The form layout is quite basic: <form> <fieldset> <label for="name">Name:</label> &l ...

How can you align the label of a v-text-field to the right in rtl languages?

I am working with a v-text-field in the following format: <v-text-field v-model="username" label="نام کاربری" /> However, I have noticed that the label appears on the left side. Is there a way to adjust it so that it displays on the right ...

Double array summation function

It is necessary for me to calculate the total coursePrice from this JSON data source here using AngularJS (javascript). I need to calculate two sums: one for each school and another for all schools combined. I have already displayed all the data in a tabl ...

Capture data from Ajax requests and store them in PHP variables

When setting up a DDBB Insert using $.ajax, I encountered an issue. $(document).on('click','.submitMessage', function(){ content=$('textarea').val(); img=$('#messageImg').val(); stdMsg=$('.ms_stdMsg ...

Experiencing issues with Firebase authentication on Nuxt app when refreshing the page for beginners

Despite my efforts of trying numerous examples and methods, I am still stuck in this situation - I have been struggling with it for the past 2 days now... The issue I am facing is that my app functions properly when I log in and click on links, but if I re ...

Ending the Overlay

I am using an overlay: <div id="overlayer" class="overlayer"> <div id="board" class="board"></div> </div> Here are the CSS properties I have applied to it: #overlayer { position:fixed; display:none; top:0; left:0; width:100%; hei ...

How to store lengthy JSON strings in SAP ABAP as variables or literals without extensive formatting restrictions

Is there a way to input lengthy JSON data into ABAP as a string literal without the need for excessive line breaks or formatting? Perhaps enclosing the string in a specific template, or utilizing a method similar to JSON.stringify(..) found in other langua ...

Automating the movement of a slider input gradually throughout a specified duration

I am working on a website that includes a range input setup like this: <input type="range" min="1036000000000" max="1510462800000" value="0" class="slider" id ="slider"/> Additionally, I have integrated some D3 code for visualizations. You can view ...