What is the most effective method for transferring and accessing data within a child form component?

This is how I am currently handling it:

Parent.vue:

// Template

<form-child :schema="schema"><form-child>

// JS

data () {
  return {
    schema: [{ // name: '', value: '', type: '' }, { //etc ... }]
  }
}

FormChild.vue:

// Template

<div v-for="field in schema">
  <input v-if="field.type === 'text'" @change="updateValue(field.name, field.value)">
  <textarea v-if="field.type === 'textarea'" @change="updateValue(field.name, field.value)">/textarea>
</div>

// JS

props: {
  schema: Arrary
}

methods: {
  updateValue (fieldName, fieldValue) {
    this.schema.forEach(field => {
      // this will update the schema in Parent.vue
      if (field.name === fieldName) field.value = fieldValue
    })
  }
}

Do you think there might be a more effective way to handle this, maybe using emit and v-model? If so, could you please show me an example of how to implement that?

Answer №1

When creating a child component, it is important to ensure that it is decoupled from the parent data structure. The child component should have separate props for `type` and `value`, along with an opaque `id` to communicate which value is being emitted.

To enable the use of `v-model` on form elements within the component, a settable computed property based on the `value` parameter can be utilized. The `set` function triggers an `input` event containing the `id` and the new value, allowing the parent to handle the update.

Update: Upon further consideration, I decided to manage the `id` in the input handler:

@input="updateField(index, $event)
.

new Vue({
  el: '#app',
  data: {
    schema: [{
        type: 'text',
        name: 'one',
        value: "1"
      },
      {
        type: 'textarea',
        name: 'two',
        value: "stuff in the textarea"
      }
    ]
  },
  methods: {
    updateField(index, newValue) {
      this.schema[index].value = newValue;
    }
  },
  components: {
    formInput: {
      props: ['type', 'value'],
      computed: {
        proxyValue: {
          get() { return this.value; },
          set(newValue) {
            this.$emit('input', newValue);
          }
        }
      }
    }
  }
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.min.js"></script>
<div id="app">
  <div v-for="field in schema">
    {{field.name}} = {{field.value}}
  </div>
  <form-input inline-template v-for="field, index in schema" :type="field.type" :key="index" :value="field.value" @input="updateField(index, $event)">
    <div>
      <input v-if="type === 'text'" v-model="proxyValue">
      <textarea v-if="type === 'textarea'" v-model="proxyValue"></textarea>
    </div>
  </form-input>
</div>

Answer №2

Instead of breaking the form into a separate component, you can simply integrate it into the parent element and utilize v-model.

new Vue({
  el: '#app',
  data: {
    schema: [{
        type: 'text',
        name: 'one',
        value: "1"
      },
      {
        type: 'textarea',
        name: 'two',
        value: "stuff in the textarea"
      }
    ]
  }
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.min.js"></script>
<div id="app">
  <div v-for="field in schema">
    {{field.name}} = {{field.value}}
  </div>
  <div v-for="field in schema">
    <input v-if="field.type === 'text'" v-model="field.value">
    <textarea v-if="field.type === 'textarea'" v-model="field.value"></textarea>
  </div>
</div>

If you prefer to create a component for reusability and are not concerned about isolating the parent from changes (although best practice is to avoid external changes to component data), you can enclose the same code within a component:

new Vue({
  el: '#app',
  data: {
    schema: [{
        type: 'text',
        name: 'one',
        value: "1"
      },
      {
        type: 'textarea',
        name: 'two',
        value: "stuff in the textarea"
      }
    ]
  },
  components: {
    formChild: {
      props: ['value']
    }
  }
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.min.js"></script>
<div id="app">
  <div v-for="field in schema">
    {{field.name}} = {{field.value}}
  </div>
  <form-child inline-template v-model="schema">
    <div>
      <div v-for="field in value">
        <input v-if="field.type === 'text'" v-model="field.value">
        <textarea v-if="field.type === 'textarea'" v-model="field.value"></textarea>
      </div>
    </div>
  </form-child>
</div>

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

By changing the name of my file to .js.erb, I am able to seamlessly incorporate erb syntax within my javascript code, but this

Currently, I am using chessboard-0.3.0.js in a rails application. Due to the rails asset pipeline setup, I've had to make adjustments to the js code specifically related to rendering images, such as Pieces. In line 445 of chessboard.js, it states: c ...

Organize array by "categories" in Javascript and preserve the original sequence

There is a dataset presented below: [ { "name": "Item1", "section": "section1", "total": 3, }, { "name": "Item1", "section": "section2", "total": 4, }{ "name": "Item1", "section": "section3", "total": 7, }, { "name" ...

"Discrepancy in results between JSON stringify and JavaScript object conversion

I need to save this object in a database, but first I have to send it to the backend. Recorder {config: Object, recording: false, callbacks: Object, context: AudioContext, node: ScriptProcessorNode…} However, after using JSON.stringify(recorder) The r ...

Error: Unable to locate the include file

Hello, I am currently a student working on a project where I am attempting to retrieve a list of books from the server and display them one by one using ejs. Here is an overview of my project structure: | |-----routes | |-----index.js |-----vie ...

Passing a variable between pages in PHP: a simple guide

In my *book_order* page, I allow users to input orders into a table called *order_management*. The order_id is auto-incremented in this table. After submitting the page, I need to pass the order_id to another page named *book_order2* where products can be ...

Using Javascript to extract formatted text from a webpage and save it to the clipboard

I've developed a straightforward tool for employees to customize their company email signature. The tool generates text with specific styling, including bold fonts and a touch of color - nothing too extravagant. When I manually copy and paste the styl ...

When the cursor hovers, a drop-down menu appears simultaneously

Currently utilizing the Bigcommerce stencil theme, I have encountered an issue where both dropdown menus appear when I hover over a link. My goal is to have only one dropdown menu pop up when hovering over a specific link. https://i.sstatic.net/paVoY.png ...

Compiling SCSS to CSS in Vue.js is a breeze

I am working on a vue js project that includes scss files. My goal is to compile these scss files into css and store them in the public folder. How can I achieve this? Should I make changes to the vue.config.js file? const path = require('path'); ...

Redirect middleware for Next.js

I am currently working on implementing a log-in/log-out feature in my project using nextjs, redux-saga, and mui libraries. // middleware.ts import { NextRequest, NextResponse } from 'next/server'; import { RequestCookies } from 'next/dist/c ...

What is a clever way to monitor the completion of a forEach loop using promises?

I'm new to promises and I'm attempting to use them for the first time. After the completion of the forEach loop, I want to call another function for additional processing. However, when using forEach, the function insertIDBEvents is only printed ...

Guide on altering the cell's background hue depending on its value through javascript

I'm dealing with a table that has 3 columns: field1 is a Category field2 and field3 contain Measures (specifically integers 1, 2, 3, 4, and 5). Is there a way to use Javascript to conditionally format the background color of cells in the table hol ...

Utilize React to dynamically load diverse data arrays into a slick slider component

I am currently working on a component that includes a slider displaying photos linked to different rooms. The next step is to move this slider to a separate page or component, which will display content for rooms, news, and promotions using different arr ...

After modifying the select option, the input field remains disabled

I successfully developed a self-contained code snippet that toggles the enable/disable state of input fields. It works flawlessly on my HTML page. Check it out below: Identification Type: <select name="Identification-Type" id="Identification-Type"& ...

Nuxt 3: Accessing the contents of a slot

Here is the code snippet for my component. I am incorporating VueUse as well, and I aim to activate the "onClickOutside" function of vueUse when a click occurs outside the slot element. However, I have been facing challenges in identifying the c ...

I am experiencing difficulties with the React-router useHistory function

Currently working on a project involving react and nodejs. Utilizing window.location.href to redirect to another page upon successful login, however, attempting to use useHistory for redirection without updating is yielding an error message: Error Uncaugh ...

Error encountered: X.setValue is not a valid function and cannot be used to set the value. However, manually inputting the value as a

When I try to use the line sseTopicString.setValue(sseValueNumber), a Type error is thrown: Uncaught TypeError: sseTopicString.setValue is not a function. Interestingly, if I output the value (string) of sseTopicString before the dot, everything works fin ...

What is causing this code to keep iterating endlessly?

I have a basic jquery script embedded in my HTML code that utilizes the cycle plugin for jQuery. The problem I'm facing is that when I interact with the slideshow using the "next" or "previous" buttons, it continues to loop automatically after that in ...

Navigating through embedded arrays in Angular

JSON Object const users = [{ "name":"Mark", "age":30, "isActive" : true, "cars":{ Owned : ["Ford", "BMW", "Fiat"], Rented : ["Ford", "BMW", "Fiat" ...

What could be the reason behind ejs not allowing if else statements when the variable is undefined?

I am attempting to replicate a rather simple example from this question here <div <% if (page_name === 'overview') { %> class="menu__menu-overviewPage menu" <% } %> class="menu"> However, when I try it on a ...

Difficulty encountered when attempting to extract a username with multiple spaces using the .split() method in Discord.js with NodeJS

Currently, I am enhancing a feature in my Discord Bot that fetches the League of Legends statistics of a player by using the command !lolid [enter_username_here] in a Discord chat room. The function works smoothly for usernames with just one word; however, ...