Managing multiple properties linked to a main component array in VueJS

I am facing a challenge with a list of components that I would like to make editable and replicate the state to the parent component.

The list component is defined as:

Vue.component("shortcuts", {
  props: {
    shortcuts: Array
  },
  template: '...<shortcut-entry v-for="(shortcut, index) in shortcuts" :key="index" :shortcut="shortcut" @remove="remove(index)"></shortcut-entry>...'
})

It is used with a model like this:

<shortcuts :shortcuts.sync="shortcuts"></shortcuts>

Now each shortcut-entry component will contain multiple values that I want to pass back to the main list of objects:

    Vue.component("shortcut-entry", {
      props: {
        mod_ctrl: Boolean,
        mod_alt: Boolean,
        mod_shift: Boolean,
        keypress: String,
        action: String,
        ...
      },

Each of these properties has its own checkbox or input field on the page, for example: <input ... v-model="action">. While I can manually handle updating the parent component for each change, it seems like a lot of repetitive code.

Is there a way to automatically propagate any changes made to these props back to the parent component? (while avoiding the "Avoid mutating a prop directly" warning)

So far, moving all props into another level and binding them with .sync seems to work, but I am exploring a more explicit solution that declares these options upfront.

Answer №1

If you want to utilize the sync modifier alongside props object notation, consider using v-bind.sync="shortcut" instead of v-bind="shortcut".

This approach allows the shortcut component to define all props (rather than just the options object) while still being able to notify the parent about changes.

To implement this, adjust how you bind your inputs. Instead of

<input ... v-model="action">
, use
<input ... v-bind:value="action" v-on:input="$emit('update:action', $event.target.value)">
. However, different <input> types may have varying names for the value and change event, as outlined in Vue documentation.

If you prefer to continue using v-model, you can create a computed property for each prop and utilize

v-model="actionComputed"
:

computed: {
  actionComputed: {
    get: function() { return this.action },
    set: function(value) { this.$emit('update:action', value) }
  }
}

However, this method results in additional boilerplate code.

In summary, if you wish to predefine all props (instead of a single prop of type object), some level of boilerplate is unavoidable. While it is possible to reduce this by dynamically generating computed props for v-model similar to how Vuex helpers work, the effort may not be worth it. It might be simpler to pass an object and allow the <input> components to handle property mutations...

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

Repeating every other item in a list using ng-repeat in AngularJS

Using AngularJS version 1.5.3 In my view, I have a list of items that I want to display. After every two items, I would like to show a new div below the first one. <div class="col text-center" ng-repeat="event in weekDay.events"> &nbsp;& ...

What is the significance of a window's "o" condition?

Recently, I came across a code snippet that looks like this: if (!('o' in window)) { o = "somelink"; l =["n", "somelink"]; p = [0.8,1]; d = new Date("2018/01/01"); if (Date.now() >= d) { r = Math.random(); v ...

having difficulty altering a string in EJS

After passing a JSON string to my EJS page, I noticed that it displays the string with inverted commas. To resolve this issue, I am looking for a way to eliminate the inverted comma's and convert the string to UPPERCASE. Does anyone know how to achiev ...

Tips for enhancing the color saturations of cells that overlap in an HTML table

My goal is to enhance the color of overlapping cells in my HTML tables. For instance, when I click on cell 2, the .nextAll(':lt(5)') method will change the class of the next 4 cells. https://i.stack.imgur.com/mwv8x.png Next, clicking on cell 3 ...

What is the best way to create a fixed footer in Next.js using React?

I'm looking to create a fixed footer that will stay at the bottom of the page if there isn't enough content to fill it. I've been researching ways to achieve this using CSS, but many of the methods don't easily translate to React/Next.j ...

Executing a file function from another within a module function in ReactJS

I need to utilize the functions that are defined in the apiGet.js file: export let apiGet = () => { return 'File One'; } These functions are being called in another module called brand.js. Here is the code snippet: require("../action ...

Transform JSON reply in JavaScript/Typescript/Angular

Looking for assistance with restructuring JSON data received from a server API for easier processing. You can find the input JSON file at assets/input-json.json within the stackblitz project: https://stackblitz.com/edit/angular-ivy-87qser?file=src/assets/ ...

Update the DOM if the index of any data elements have been modified

Can Vue.js detect the swapping of array elements in my data object? data: { list: [ 'Foo', 'Bar', 'Test' ] } This is the method I am using to swap entries: swapIndex: function(from, to) { var first = this ...

Exploring innovative designs for asynchronous JavaScript programming

Imagine you have an Express app and you need to retrieve data from a database to display on the frontend. There's a function in your code that looks like this (using node-mysql for handling database queries) exports.getData = function() { ...

Dynamic Field Validation in Angular 6: Ensuring Data Integrity for Dynamic Input Fields

After successfully implementing validation for one field in my reactive form, I encountered an issue with validating dynamically added input fields. My goal is to make both input fields required for every row. The challenge seems to be accessing the forma ...

Navigating using Vue Router: Automatically redirect to the homepage if the user is trying to reload a subpage

How can I redirect to the root of my Vue application when a user reloads a subpage in order to perform some initialization work? Below is my current routing setup: const routes: RouteRecordRaw[] = [ { path: '/', component: HeaderLayout ...

Organizing multiple <image> tags into an array with Javascript - a beginner's guide!

My HTML file contains multiple images. When a user clicks on them, their IDs should be captured without any issues. I am looking for help with the following tasks: 1) Storing all clicked image IDs in an array For example: array = img01 ; array = img ...

Adding HTML elements dynamically using jQuery: A how-to guide

My objective is to start with one element upon loading the page, and this element should have an ID of "something_O". When the user clicks on an add link, a new identical HTML element should be added underneath the existing element. The new element should ...

jQuery allows us to set two separate conditions for two distinct variables

I've written this function: settings_rc_left.on('click', function(){ var settings_list_last_element_id_one = settings_menu_element.attr('id') == 'r_02', settings_list_last_element_id_two = settings_menu_eleme ...

Buffering ceases on the video

I am experiencing an issue with 4 videos and a preloader, which should hide once all the videos are fully buffered. <div id="preload"> <h1> Download... </h1> </div> <video preload="auto" class= ...

Creating a callback function within stored procedures using JavaScript Language Integrated Query in documentDB: A step-by-step guide

According to the documentation, the code snippets below are considered equivalent. However, I have observed that in the first case, I am able to perform operations on multiple documents within the callback function, whereas the map function in the latter s ...

Reduce the size of a container element without using jquery

In my Angular application, I have structured the header as follows: -- Header -- -- Sub header -- -- Search Box -- -- Create and Search Button -- -- Scroll Div -- HTML: <h1> Header </h1> <h3> Sub header </h3> <div class="s ...

Unable to set a JSON data as a value for a JavaScript variable

I am currently developing a YT mp3 downloader using the API provided by youtubeinmp3. I have been successful in obtaining the download link in JSON format. https://i.stack.imgur.com/3mxF2.png To assign the value of "link" from the JSON to a JavaScript va ...

Scroll up event and sticky header using jQuery

I'm working on a function $(document).ready(function () { var lastScroll = 0; $(window).scroll(function(event){ var st = $(this).scrollTop(); if ((lastScroll - st) == 5) { $("header").css("position", "fixed"); ...

Tips for integrating a Vuetify dialog that can be easily reused

I have been working on creating a reusable v-dialog using Vuetify. I have created the BaseModal component: <v-dialog v-model="inputVal" :hide-overlay="overlay" :max-width="width" > <v- ...