Is it possible to monitor child component values within the parent component without relying on emit?

I created a unique component named HobbyForm, which consists of a simple form with two controls - a checkbox and an input field. This particular component is being utilized within a parent component called Content, alongside similar 'form' components.

<template>
    <form>
       <div class="row align-items-center">
            <div class="col-1">
                <Checkbox id="isHobbyActive" :binary="true" v-model="isActive"/>
            </div>
            <div class="col-5">
                <InputText id="hobby" placeholder="Hobby" type="text" autocomplete="off" v-model="hobby"/>
            </div>
        </div> 
    </form>
</template>
<script>
export default {
    name: 'HobbyForm',
    data() {
        return {
            hobby: {
                isActive: false,
                hobby: null
            }
        }
    },
}
</script>

The structure of my Content component looks like this:

<template>
    <language-form></language-form>
    <hobby-form v-for="(hobbie, index) in hobbies" :key="index" v-bind="hobbies[index]"></hobby-form>
    <Button label="Add Hobby" @click="addHobby"></Button>
</template>
<script>

export default {
  name: "Content",
  components: {
    LanguageForm,
    HobbyForm
  },
  data() {
    return {
      language: '',
      hobbies: [
        {
          isActive: false,
          hobby: null
        }
      ]
    };
  },
  methods: {
      addHobby() {
        this.hobbies.push({
          isActive: false,
          hobby: null
        });
      }
  },
};
</script>

The main goal is to be able to include more instances of the HobbyForm component in order to append additional hobby records to the hobby data property. However, I am unsure of how to manage and retrieve these values from my parent without manually triggering an emit event from my child components to update the data in the parent component.

Could you provide guidance on accessing the data of my child components from the parent and incorporating it into my array?

Answer №1

The method of passing parent data into a child component using

v-bind="hobbies[index]"
in the current form does not make sense because the child component (HobbyForm) does not have any props to receive data from the parent...

To correct this:

  1. Remove data() from the child component HobbyForm
  2. Instead, declare a prop of type Object
  3. Bind the form items to the properties of that Object
  4. Pass the object into each instance of HobbyForm
<template>
    <form>
       <div class="row align-items-center">
            <div class="col-1">
                <Checkbox id="isHobbyActive" :binary="true" v-model="hobby.isActive"/>
            </div>
            <div class="col-5">
                <InputText id="hobby" placeholder="Hobby" type="text" autocomplete="off" v-model="hobby.hobby"/>
            </div>
        </div> 
    </form>
</template>
<script>
export default {
    name: 'HobbyForm',
    props: {
      hobby: {
        type: Object,
        required: true
      }
    }
}
</script>

Even though props are meant to be one way only and children should not mutate prop values, this scenario is different as you are updating (via a v-model) the properties of the passed object rather than directly mutating the prop value itself (refer to the note at the end of the One-Way Data Flow section)

Update the parent code to:

<hobby-form v-for="(hobby, index) in hobbies" :key="index" v-bind:hobby="hobby"></hobby-form>

Demo:

const app = Vue.createApp({
  data() {
    return {
      hobbies: [{
        isActive: false,
        hobby: null
      }]
    };
  },
  methods: {
    addHobby() {
      this.hobbies.push({
        isActive: false,
        hobby: null
      });
    }
  },
})

app.component('hobby-form', {
  props: {
    hobby: {
      type: Object,
      required: true
    }
  },
  template: `
  <form>
       <div class="row align-items-center">
            <div class="col-1">
                <input type="checkbox" id="isHobbyActive" v-model="hobby.isActive"/>
            </div>
            <div class="col-5">
                <input type="text" id="hobby" placeholder="Hobby" autocomplete="off" v-model="hobby.hobby"/>
            </div>
        </div> 
    </form>
  `
})

app.mount('#app')
<script src="https://unpkg.com/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="07717262473429362932">[email protected]</a>/dist/vue.global.js"></script>
<div id='app'>
   <hobby-form v-for="(hobby, index) in hobbies" :key="index" v-bind:hobby="hobby"></hobby-form>
   <button @click="addHobby">Add Hobby</button>
   <hr/>
   <pre> {{ hobbies }} </pre>
</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

Exploring the functionality of incorporating double curly braces from Vue.js within a PHP string parameter

As I combine Vue.js, PHP, and HTML, I have encountered a small problem. In the HTML section below: <button class="task button is-fullwidth is-flex" v-for="task, taskid in list.list"> <span class="icon"> ...

Implementing a transition to activate upon data loading in a Vue.js component – here's how!

Currently, I am immersed in a project utilizing vue.js and vue-router. Within my Vue application, I have a section dedicated to displaying news fetched from an API that functions as a blog. To load this news data into the component, I am utilizing the rou ...

Running the command "npm start" is resulting in an error message stating: "ENOENT: no such file or directory ... package.json"

After successfully creating a React app using NPX, I encountered an issue when trying to run npm start. The error message that appeared is as follows: $ npm start npm ERR! code ENOENT npm ERR! syscall open npm ERR! path C:\Users\Administrateur.TE ...

Using Immutable JS to Generate an OrderedMap from a List

I possess a List const results = [94, 88, 121, 17]; and I also own a Map const posts = { 94: { title: 'Foo bar', content: 'Blah blah blah...' }, 88: { title: 'Bar Foo', content: 'Blah blah blah...' }, 121 ...

Steps for displaying the output of a post request in printing

I am currently working on creating a basic search bar functionality for daycares based on user input. I am utilizing a post request to an API and receiving back a list of daycares that match the input. Below is the code snippet: <template> <div ...

How do you find a specific value in an array using a function?

As a newcomer to JavaScript and StackOverflow, I am currently working on creating a function to search for a specific value within an array I have created. Although I have written what I think is a functioning function, it seems to not be working. Any idea ...

What could be causing the confusing "undefined" result when parameters are passed to a mapped getter function

I have a set of getters that are designed to receive an id and return the corresponding data. I've connected these getters to a component, but when passing a parameter, it ends up being undefined. Component: <template> <div> ...

Implementing an autosuggest feature for the TagsInput component

When developing my website, I utilized JavaScript, the React framework, and a library called mui. One of the user input features on my site is powered by TagsInput, allowing users to input data, press enter, view the tag, and optionally delete it. Unlike ...

Securing client side routes in Vue.js: Best practices

Currently, I am in the process of developing a spa using Vue.js as the front end framework. It interacts with a back-end system that utilizes pure JSON and jsonwebtokens for security. While I am more experienced with the React ecosystem, my new role requir ...

Resetting text in an input field using CSS

Here is the fiddle link for reference: http://jsfiddle.net/a765q/1/. I noticed that when I click the reset button, the text color changes to grey. Any ideas on how to fix this? ...

Learn the technique of hovering over an image to see it blur and reveal overlay text

Currently, I am in the process of creating my portfolio website and after experimenting with some code, I was able to achieve the desired outcome. <div id="nytimes" class="portfolio-thumbnail" style="left: 100px; top: 80px;"> <span class="text ...

Issue with Vuetify Combobox: Value not updating accurately

Whenever I try to save a value from my Vuetify combobox, it seems to store the previously selected value instead of the new one if I click the save button directly without deselecting the combobox. The correct value is only stored when I manually unselect ...

`Inability to Execute Callback Function in JQuery AJAX POST Request`

I've created a simple JavaScript method that sends an AJAX request to a server and is supposed to execute a callback function. However, I'm facing an issue where the specified callback function isn't being executed. Despite this, when I chec ...

Deactivate a Button until Another One is Clicked in React

Is there a way to disable the submit button until a rating has been provided? My Current State this.state = { stars: [ { active: false }, { active: false }, { active: false }, { active: false }, { active: fal ...

Locating every quadrilateral within a mesh

I'm currently using Three.js to load a mesh and I am attempting to texture each quad individually. At the moment, I am able to texture each face (triangle), but I am unsure of how to determine if the current triangle and the last triangle are part of ...

Is your prop callback failing to return a value?

I am currently utilizing a Material UI Table component in my ReactJS project and I would like to update a state variable whenever a row is selected or deselected. The Table component has an onRowSelection prop that gets triggered each time a row is is sele ...

Iterate through the array and add each number to a separate array

I am currently facing an issue with the code snippet provided below. var array = [1, 3, 2] var newArray = [] getNewArray() { for (let i = 0; i < array.length; i++) { for (let x = 0; x < array[i]; x++) { this.newArray.pus ...

Similar to `util.inspect` in Node.js, Deno also has a function

Is there a utility function in Deno that can stringify an Object or primitive similar to Node.js util.inspect? For instance, if I have a JSON object in Node.js and want to display its contents: > m = {k1:'v1', k2:'v2'} { k1: ' ...

JSON array cannot be traversed

I am retrieving an array from my API response in NODEJS: res.json(friends) [ { "id": 7795239, "username": "janesmith" }, { "id": 1363327, "username": "johnsmith" } ] However, I am encountering difficulties ...

Creating a dynamic URL for route model binding using Axios

I need assistance in creating a Vue Axios URL using slug and id, but I'm facing difficulties. Could someone please lend me a hand? axios.get('http://localhost/BUproject/postsByUser/' + slug / +id) .then(response => { this.po ...