Bidirectional data binding in Vue.js enables seamless communication between parent and child components, allowing for dynamic

Trying to implement v-for and v-model for two-way data binding in input forms. Looking to generate child components dynamically, but the parent's data object is not updating as expected.

Here's how my template is structured:

<div class="container" id="app">
  <div class="row">
    Parent Val
    {{ ranges }}
  </div>

   <div class="row">
     <button 
        v-on:click="addRange"
        type="button" 
        class="btn btn-outline-secondary">Add time-range
     </button>
    </div>

  <time-range 
    v-for="range in ranges"
    :box-index="$index"
    v-bind:data.sync="range">
  </time-range>

</div>

<template id="time-range">
  <div class="row">
    <input v-model="data" type="text">
  </div>
</template>

And the corresponding JavaScript:

Vue.component('time-range', {
  template: '#time-range',
  props: ['data'],
  data: {}
})

new Vue({
  el: '#app',
  data: {
    ranges: [],
  },
  methods: {
    addRange: function () {
        this.ranges.push('')
    },
  }
})

For reference, I have created a JSFiddle as well: https://jsfiddle.net/8mdso9fj/96/

Answer №1

Note: dealing with an array can complicate things as you are unable to modify an alias (the v-for variable).

An alternative method that is not frequently discussed is to capture the native input event as it rises to the component. This approach can be simpler than having to propagate Vue events upwards, provided there is an element triggering a native input or change event within your component. In this example, I am using change, so the change will be noticed only when you leave the field. Due to the array issue, I need to use splice to ensure Vue registers the change to an element.

Vue.component('time-range', {
  template: '#time-range',
  props: ['data']
})

new Vue({
  el: '#app',
  data: {
    ranges: [],
  },
  methods: {
    addRange: function () {
        this.ranges.push('')
    },
  }
})
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div class="container" id="app">
  <div class="row">
    Parent Val
    {{ ranges }}
  </div>
  
   <div class="row">
     <button 
        v-on:click="addRange"
        type="button" 
        class="btn btn-outline-secondary">Add time-range
     </button>
    </div>

  <time-range 
    v-for="range, index in ranges"
    :data="range"
    :key="index"
    @change.native="(event) => ranges.splice(index, 1, event.target.value)">
  </time-range>
</div>

<template id="time-range">
  <div class="row">
    <input :value="data" type="text">
  </div>
</template>

When using the .sync modifier, the child component should emit an update:variablename event that the parent will catch and handle accordingly. In this scenario, variablename is data. Despite using the array-subscripting notation, as v-for alias variables cannot be modified, Vue handles .sync on the array element, eliminating the need for splice.

Vue.component('time-range', {
  template: '#time-range',
  props: ['data'],
  methods: {
    emitUpdate(event) {
      this.$emit('update:data', event.target.value);
    }
  }
})

new Vue({
  el: '#app',
  data: {
    ranges: [],
  },
  methods: {
    addRange: function () {
        this.ranges.push('')
    },
  }
})
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div class="container" id="app">
  <div class="row">
    Parent Val
    {{ ranges }}
  </div>
  
   <div class="row">
     <button 
        v-on:click="addRange"
        type="button" 
        class="btn btn-outline-secondary">Add time-range
     </button>
    </div>

  <time-range 
    v-for="range, index in ranges"
    :data.sync="ranges[index]"
    :key="index">
  </time-range>

</div>

<template id="time-range">
  <div class="row">
    <input :value="data" type="text" @change="emitUpdate">
  </div>
</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

What is the best way to conceal two Bootstrap divs that should not both be visible at the same time?

I am working with two different types of charts: an Emotion chart and a Polarity chart. To control the visibility of these charts, I have implemented two buttons, one for each chart. The functionality is such that when the first button is clicked, only the ...

The instanceof operator does not recognize the value as an instance and is returning false, even though it

Is there a method to verify the current instance being used? This is what I am logging to the console: import { OrthographicCamera } from 'three'; // Later in the file: console.log(camera instanceof OrthographicCamera, camera); and the result ...

Limiting the combinations of types in TypeScript

I have a dilemma: type TypeLetter = "TypeA" | "TypeB" type TypeNumber = "Type1" | "Type2" I am trying to restrict the combinations of values from these types. Only "TypeA" and "Type1" can be paired together, and only "TypeB" and "Type2" can be paired tog ...

React - Children components in an array not updating when props are modified within a callback function

The question may be a bit unclear, so let me provide further explanation. This is a personal project I am working on to improve my understanding of React basics and socket.io. Within this project, I have developed a CollapsibleList component and a NestedL ...

How can I stop v-dialog from closing automatically?

Utilizing the <v-dialog> component in my web app to display a form, I am facing the challenge of implementing an unsaved changes dialog that pops up when a user attempts to close the form without saving. The dilemma lies in preventing the default clo ...

Steps to generating a dynamic fabric canvas upon opening a new window

There seems to be an issue with the code below. When I click the button next to the canvas, my intention is to have a new window open displaying the canvas in full view. However, it's not working as expected. Can someone please assist me in troublesho ...

Exploring Firebase database with AngularJS to iterate through an array of objects

I'm working on an app that pulls data from a Firebase database, but I'm running into an issue. When I try to loop through the data and display it on the page, nothing shows up. However, if I use console.log to output the data, it's all there ...

The function initiates without delay upon meeting the specified condition

I am looking to trigger a function automatically upon certain dynamically changing conditions in my JavaScript code. I attempted using the document.body.onload method, but it did not work as expected. document.body.onload = myFunction() function myFunct ...

The addEventListener method fails to respond to changes in input

Can someone assist me with this issue? I am facing a problem where the input.addeventlistener is not detecting files on change. My setup involves using Vue with Rails. I am looking to trigger the event listener in the mount hook of a Vue component. mo ...

What could be causing my Wikipedia opensearch AJAX request to not return successfully?

I've been attempting various methods to no avail when trying to execute the success block. The ajax request keeps returning an error despite having the correct URL. My current error message reads "undefined". Any suggestions on alternative approaches ...

Enhancing web page interactivity through dynamic element names with Javascript and jQuery

I have an interesting HTML setup that looks like this: <div> <input type="text" name="array[a][b][0][foo]" /> <input type="text" name="array[a][b][0][bar]" /> <select name="array[0][a][b][baz]>...</select> </div> ...

Tips for protecting API keys with Nuxt and ensuring their authentication

Currently, I am utilizing Nuxt, including SSR, PWA, Vuejs, Node.js, Vuex, and Firestore. I am seeking guidance or examples regarding the following: How can I ensure the security of an API key, such as for accessing the MailChimp API? I am unsure of how v ...

Counting gettext values up to a specified number of occurrences

When clicking a button, the elements within this div receive number values. If a specific pattern is reached in the text of these elements, the test should be ended. For instance, if there are 5 elements under the "someelement" div and three of them conta ...

"Kindly complete all mandatory fields" - The undisclosed field is preventing me from submitting

I am facing an issue with my WordPress page that has Buddyboss installed along with Elementor pro as the Pagebuilder. The Buddyboss plugin provides Facebook-like functions on the website. While it is easy to comment on posts within the Buddy Boss system, I ...

The JSON.stringify method may not accurately reflect the original object that was converted into a string

Working on a Connect Four app for my school project has been an interesting challenge. At the moment, I am grappling with JSON.stringify and trying to encode an object that holds a two-dimensional array of "hole" objects to eventually send it to the server ...

There is no way to avoid a PHP variable being displayed in a JavaScript alert box

It may sound silly, but I've spent hours trying to escape this PHP variable that contains post data: $post=array ( 'offers' => '90', 'pn' => '2', 'ord' => 'price', 'category_s ...

Resetting a JQuery button to its initial state

I have a button that, when clicked, rotates to 25deg thanks to Jquery. Now, I want it so that if I click the button again, it returns to its original position. Here is what I have tried: $(document).ready(function() { $(function() { ...

The size of the popup does not align properly with the content within it

After creating an extension for Chrome, I specified the dimensions of the popup to be 600 x 300 px. Everything was working perfectly until Chrome updated to version 27. As shown in the screenshot, I set the width and height using CSS, but there is still a ...

I am struggling to make Angular Charts display labels the way I want them to

Struggling to customize an angular chart for my project. The x axis should display dates and the mouse over should show client names, all retrieved from an array of resource objects in a loop. The loop code snippet is as follows: angular.forEach(charts, ...

Employing AJAX, execute a synchronous function asynchronously (Javascript)

Here's a code snippet for the sync function. I've been calling it inside an Ajax, but apparently it's deprecated because it's synchronous. Is there any way to make it run as if it were asynchronous? Or is there a way to convert it into ...