In Vue JS, what is the best way to update a Child component after clicking a button on the Parent Component?

In my application, I have a setting option that updates from the Parent Component. The setting data is saved in localStorage and three Child Components utilize this setting data.

<P>
  <c1> </c1>
  <c2> </c2>
  <c3> </c3>
</P>

I am looking for a way to automatically refresh or update the three components when the setting data is updated. For instance, if I press a button on the Parent component, all three Child components should reflect the new value.

------------------------ UPDATED ------------------------------

TEMPLATE PART:

<template>
  <div class="main-content">
   <div class="main">

<!-- COMPONENT -->
<div class="row">
   <div class="padpad">
      <div class="col-md-6">
         <app-colma></app-colma>
      </div>
      <div class="col-md-3">
         <app-colmb></app-colmb>
      </div>
 
   </div>
</div>;

...

</template>

SCRIPT CODE:

<script>
import ColmA from './ColmA.vue';
import ColmB from './ColmB.vue';
import ColmTotal from './ColmTotal.vue';
export default {
  components: {...},
name: 'main-content',
data() { ... },
methods: {
    onSubmit: function(){ ... }
},

created: function () {
this.fetchData();
}

}
</script>

COMPONENT CODE:

<script>
export default {
  name: 'colma',
  data () { ... },
  methods: { ... },

created: function () {
this.fetchData();
}
}
</script>

Answer №1

When utilizing Vue.JS, it is advisable to stick with Vue.JS itself - The parent component should hold a model that stores your settings as reactive data. This model can then be passed down to child components as props, where the component sets up a watcher for any changes in the prop value.

var localStore = { reason: 'Fake, because no localStorage in Sandbox' };

Vue.component('rows', {
  props: ["order"],
  data: function(){ return { values: [] } },
  template: `<ul><li v-for="v in values">{{v}}</li></ul>`,
  created: function() { this.fetchValues() },
  watch: { order: function() { this.fetchValues() } },
  methods: { fetchValues: function() {
    /* Placeholder for an ajax-call with order as a parameter */
    this.values = ( this.order == 'ascending' ) ? [1,2,3] : [3,2,1]
  } }
})

new Vue({
  el: '#main',
  data: { order: 'ascending' },
  created: function() {
    if ( localStore.order ) {
      this.order = localStore.order;
    }
  },
  watch: { order: function() {
    /* Save any change on order in the local storage */
    localStore.order = this.order;
  } }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.js"></script>

<div id="main">
  <select v-model="order">
    <option value="ascending">Sort Ascending</option>
    <option value="descending">Sort Descending</option>
  </select>

  <rows :order="order"></rows>
</div>

Answer №2

To handle this situation differently, one approach is to trigger a custom event from the child component when there is a change (originating from the child). Subsequently, this event can be detected and acted upon in the parent component, which then calls a method. This method can, in turn, execute child methods to update the relevant values.

The fundamental question here is: why resort to such steps? If the parent component serves as the ultimate source of truth (i.e., passing data via props to child components), monitoring these prop changes or utilizing computed props to retrieve updated values should suffice. In essence, there's no necessity for events to activate methods at all.

In summary, your operational strategy could be summarized as follows:

  1. Send parent values (maintained in parent data) as props to child components. The child components will automatically adjust their inherited properties based on updates in these props.

  2. The parent configuration settings can also be stored in localStorage concurrently. This can be accomplished by consistently watching for alterations in parent data using the watch functionality. When necessary, you can read from localStorage again during parent remounting (e.g., page reload)—leveraging the mounted lifecycle hook. The resultant modifications would, once more, propagate to child components per point #1.

An illustrative example (for demonstration of the localStorage feature functionality, please refer to this fiddle since code excerpts are confined within sandboxes):

Vue.component('child-component-a', {
  template: '<div><h2>Child component A</h2><p>I multiply inherited parent value by 2: <strong>{{ computedNumber }}</strong></p></div>',
  props: {
    number: {
      type: Number
    }
  },
  computed: {
    computedNumber() {
      return this.number * 2;
    }
  }
});

Vue.component('child-component-b', {
  template: '<div><h2>Child component B</h2><p>I divide inherited parent value by 16: <strong>{{ computedNumber }}</strong></p></div>',
  props: {
    number: {
      type: Number
    }
  },
  computed: {
    computedNumber() {
      return this.number / 16;
    }
  }
});

var app = new Vue({
  el: '#app',
  data: {
    parentNumber: 1024
  },
  watch: {
    parentNumber() {
      // Store parent number in localStorage when updated
      // *NOTE: Disabled in this code snippet since it is sandboxed
      // localStorage.setItem('parentNumber', this.parentNumber);
    }
  },
  mounted() {
    // Overwrite parent data if localStorage is found
    // *NOTE: Disabled in this code snippet since it is sandboxed
    // if (localStorage.getItem('parentNumber') !== null) {
    //   this.parentNumber = localStorage.getItem('parentNumber');
    // }
  }
});
html {
  font-family: Arial, sans-serif;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div id="app">
  <div>
    <h1>Parent component</h1>
    <p>I have a value of <strong>{{ parentNumber }}</strong>.</p>
    <p>But wait, you can change my number!</p>
    <input v-model="parentNumber" type="number" />
  </div>
  <child-component-a v-bind:number="parentNumber"></child-component-a>
  <child-component-b v-bind:number="parentNumber"></child-component-b>
</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

Is there a way to change an element's display to 'block'? (see more information below)

I'm having an issue with my event listener for a button that is supposed to change the css of #popUpForm. It seems to only work when I add inline css directly to #popUpForm. Is there a way to achieve this without using inline css and instead setting t ...

Is there a way to select only a single line from an HTML document?

Is there a way to extract just one specific line from an HTML file? Let's say we have the following file: <!DOCTYPE html> <html> <head></head> <body> This is a test string. This is another test st ...

Monitor the status of an AJAX request for fetching JSON data in a Rails application

My JS code fetches JSON data from a controller method in a Rails app: $.ajax({ xhr: function() { var xhr = $.ajaxSettings.xhr(); xhr.onprogress = function(e) { if (e.lengthComputable) { console.log(e.loaded ...

Tips for setting up a range slider for decimal numbers

I have implemented the following code for a range slider. It works perfectly fine for integer values like 1 and 100, but I am facing issues when trying to use decimal values. I attempted to substitute 1 with 0.1 but it did not yield the desired result. ...

Add all elements except for the last one

<div id="container"> <div class="sub">a</div> <span id="add">add</span> </div> $('#add').click(function(){ $('#container').append('<div class="sub">a</div>&ap ...

Calculate the total amount from the selected items on the list, depending on the clicked ('active') element

My main objective is to achieve the following: Before any clicks || After the user selects the desired item After conducting some research, I successfully implemented this using vue.js https://jsfiddle.net/Hanstopz/Lcnxtg51/10/ However, I encountered ...

Setting the default TAB in a specific Menu Tab within the Menu Bar

I'm encountering some issues with this code. Specifically, the menu bar JavaScript is automatically clicking on the Second TAB instead of the First TAB when run. JS CODE. var dolphintabs = { subcontainers: [], last_accessed_tab: null, ...

Unable to locate the slim JWT token in the axios request

Currently, I am in the process of creating a Vue js/Vuetify website that utilizes a PHP Slim Framework API with tuuopla slim-jwt-auth serving as the middleware for JWT token authentication. While the unprotected routes are functioning correctly, I have enc ...

What is the best way to use regular expressions in Javascript to validate an empty JSON response?

I'm encountering an issue where my ajax response is coming back empty with multiple lines of blank spaces. I need to figure out how to verify this in my success function. Is there a way to use regex in JavaScript to check for an empty JSON response? ...

I'm curious, is there a way to keep track of the source styles definition (sass, scss) in Vue as we

My goal is to incorporate styles from external libraries while maintaining the original reference to their library name. In traditional HTML, I would embed minified CSS in index.html using the <style> tag, but for customization purposes, I need to u ...

issues with the handler not functioning properly in html and javascript

<form method="post" action="."> <label class="input-label">Enter Your First Name</label><input field="first_name" class="input-edit" maxlength="30" type="text" value="{{ user.first_name }}" /> <label class="i ...

Automatically refresh a pair of pages in sequence

Seeking advice on how to execute the following steps in JavaScript: - Pause for 120 seconds - Access http://192.168.1.1/internet-disconnect (in an iframe or similar) - Pause for 3 seconds - Access http://192.168.1.1/internet-connect - Repeat Here is ...

Create a div element that can be expanded on smaller devices

Is it possible to expand a div while hovering on a small or x-small device? I want to achieve something like this: https://i.sstatic.net/doJKa.png Currently, I can only hide the yellow div when the page is displayed on a small device. I am looking for a ...

Enhance Data3 Sankey to disperse data efficiently

There are a few instances where the D3 Sankey spread feature is showcased here. However, it seems that this specific function is not included in the official D3 Sankey plugin. Is there anyone who can assist me in obtaining the code for the Spread function ...

What is the best way to stop a series of Ajax promises from continuing?

Managing multiple ajax requests that are dependent on each other can be tricky, especially when you need to stop the chain if one of the requests returns false. Check out this sample code snippet below: // Implementing a promise chain return this.getBan ...

Straightforward JSON issue

I am new to JSON and I need to work with it now. I have tried several examples from the jQuery page, but they don't seem to be working for me. I have a *.php file that generates a string. From what I understand, this is how I pass JSON data from PHP ...

Ways to add AJAX information to select2

I am currently utilizing a select2 dropdown feature and I am attempting to configure it in such a way that it dynamically displays the leads based on the JSON response. As you can observe in the image provided below, the text correctly yields a JSON array ...

Encountering an 'Unknown provider' error while running a unit test with AngularJS and Jasmine

I am facing an issue while writing a unit test for a controller in my application. Jasmine is showing an 'Unknown provider' error related to a provider I created for fetching template URLs. This provider is injected into a config function that is ...

Successfully transferring canvas image to server. Saving empty picture file

I have a piece of code that creates an image from an equation editor when the save button is clicked and displays it on a canvas. However, after displaying it, I am having trouble saving it as the saved image appears blank. Can someone please help me ident ...

Generating dynamic dropdown menus in PHP

I'm currently working on a project that involves creating dynamic drop down lists in PHP using JavaScript. I've managed to fetch the value from the first dropdown list and display the corresponding values in the second list. However, the second l ...