The proper method for transmitting information to a custom input component embedded within another component

I have recently made the switch from React to Vue and I am really impressed by the v-model feature that Vue offers. However, I am now facing a dilemma and struggling to figure out the best way to handle this situation in a more Vue-appropriate manner.

This is the structure of my component tree:

- FormContainer
  -FormView
    - CustomInput
      - input

My state is residing in FormContainer, let's say we have properties like name and age. I want to find a solution without resorting to custom setter methods, similar to how I would use v-model. How can I efficiently pass the data down to the input component?

Currently, I have implemented it as follows:

// within my container
<form-view :name="name" :age="age" />

// within my form view, I have something like
<custom-input v-model="age"/>
<input v-model="name" />

Unfortunately, both approaches are not working as expected, resulting in an error stating Avoid mutating a prop directly.

I wish to achieve something like:

<form-view @age="age" :age="age" @name="name" :name="name"/>

or a similar approach. Please advise if you need further clarification on this matter.

Answer №1

After providing answers to this question twice, I felt they were not quite suitable for your needs and decided to remove them.

In essence, you are looking for events to propagate from the elements where they occur to the Vue instance that holds the data. While Vue events do not naturally bubble up, native events do. By leveraging native event binding such as @input.native, you can capture a native event like input at any component higher in the hierarchy.

For the scenario described, if the name and age data reside in the top-level Vue instance, the outermost component can accept them as props using the .sync modifier. This means that any update:name or update:age events triggered by the component will update these data items successfully.

Within the form-view component, there is an ordinary input element generating native input events. To ensure these events cascade upwards as update:name events, we handle it as follows:

<input :value="name" @input="$emit('update:name', $event.target.value)">

The intriguing part comes when dealing with the nested custom-input component within the form-view component. Here, a native input event is produced somewhere within its structure. Instead of catching and bubbling it up at each level, simply let it arise naturally and capture it at the root of the custom-input component, emitting the necessary update:age event:

<custom-input :value="age" @input.native="$emit('update:age', $event.target.value)">

Combining all these steps, we pass two variables through various components to input elements, utilize two input event handlers, and avoid using computed properties altogether.

new Vue({
  el: '#app',
  data: {
    name: 'Jerry',
    age: 21
  },
  components: {
    formView: {
      props: ['age', 'name'],
      components: {
        customInput: {
          props: ['value']
        }
      }
    }
  }
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script>
<div id="app">
  <div>Name: {{name}}</div>
  <div>Age: {{age}}</div>
  <form-view :name.sync="name" :age.sync="age" inline-template>
    <div>
      <custom-input :value="age" @input.native="$emit('update:age', $event.target.value)" inline-template>
        <div>
          Age: <input :value="value">
        </div>
      </custom-input>
      <div>Name: <input :value="name" @input="$emit('update:name', $event.target.value)"></div>
    </div>
  </form-view>
</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

Avoiding JavaScript onclick event using JSON information

Here's a situation I'm dealing with: I have a button created using PHP that triggers a JavaScript onclick event: <button onClick='edit(this, "<?php echo $this->result[$i]["type"]; ?>","<?php echo $quality; ?>", "<?php e ...

Invoke a TypeScript function within JavaScript code

As a result of the limitations of IE10 and earlier versions, I find myself in need to reimplement the Import/Upload functionality that I had initially created since FileReader is not supported. After some consideration, I have opted to utilize an iFrame in ...

Tips for initiating a function for all ng-click events in AngularJS

I have created a web application using Node.js for managing mongoDB databases. The application has various click events that perform CRUD operations to alter the database's status. Each ng-click triggers a function to execute the corresponding action, ...

Flashing white screen when transitioning between pages on phonegap iOS system

I'm currently using phonegap for my iOS application project. Interestingly, I've noticed a slight white flicker/flash when navigating between pages in the app. To address this issue, I have refrained from using jquery mobile and instead relied ...

What is the most effective method for transmitting a zip file as a response in Azure functions with node.js?

With the Azure function app, my goal is to download images from various URLs and store them in a specific folder. I then need to zip these images and send the zip file back as a response. I have successfully achieved this by following these steps: Send ...

The Express server powered by Node.js is failing to send responses back to HTTP requests initiated from a JavaScript file, despite successfully receiving and processing the requests

I am facing an issue with my setup where I have both a node-js server and an apache server running on the same machine. One of my javascript files is sending an HTTP request to the node-js server, which receives the file, reads the data, and puts it in the ...

Distributing a library of components using Vite, Vue 3, and Typescript to npm

My current challenge involves publishing a Vue 3 component library with Vite, all written in Typescript. The issue I'm facing is that the type definitions are not being included in the package when imported into another project. Upon importing the co ...

Having trouble with the open and create new post button not functioning properly

The submit post button, user name, and logout button are not functioning properly. Can anyone assist with this issue? F12 and jsintrc are not providing any useful information. Below is the HTML code for the create new post button which should direct to a ...

Struggle encountered in obtaining the value of a DatePicker in VueJS

Currently, I am utilizing the vue-hotel-datepicker component for managing dates. It is functioning well; however, I am encountering an issue when attempting to retrieve the updated date value in my JavaScript code. Any advice or assistance on how to captur ...

Learn how to successfully upload an image using React and Node without having to rely on

I am currently exploring file uploading in react/node. Instead of passing files directly into the API request, I am passing them within the body of the request. Here is a snippet of my react code: import React, { Component } from 'react'; import ...

A dynamic display featuring four columns that showcase unique content every day of the week

As a beginner in coding, I am attempting to design a page with 4 columns that will showcase different titles and descriptions each day of the week. My goal is to have a set of titles and descriptions displayed on Monday, a different set on Tuesday, and so ...

Which is the best way to include parameters in jQuery ajax calls: adding them to the URL or to the object

When it comes to passing parameters to the server using jQuery get, post, or ajax, is there a more efficient method: attaching them to the URL or adding them to an object? Is the choice dependent on specific circumstances? For example, consider the follo ...

Is there a way to switch the default text mode from plain to code, such as HTML?

Is there a way to switch from plain text mode to code mode, specifically HTML, in Sublime? I often find the need to change the mode from plain text to HTML when working on projects. ...

Populating an item in a for each loop - JavaScript

In the following example, I am struggling to populate the object with the actual data that I have. var dataset = {}; $.each(data.body, function( index, value ) { dataset[index] = { label: 'hello', ...

Sign-in options displayed in a drop-down menu

I have successfully implemented a jQuery animation for a dropdown sign in div. The sign up form is integrated with PHP to verify the existence of users in the database. However, I came across an issue where if I echo something, the dropdown menu disappears ...

"Exploring the use of jQuery to access dynamic CSS properties such as :before and implementing filter

I am facing an issue with jQuery and CSS. Below is the code snippet: $("#test").append($("<div>",{ style:"width:48%; margin-left:1%; margin-right:1%; margin-bottom:10px; float:left; background-image:url(http://test.png); filter:brigh ...

The outcome of a MySQL query involving JSON_OBJECT() is a string value

I have crafted a query that extracts posts from a table and includes information about each post's author: SELECT post.id, post.text, post.datetime, JSON_OBJECT( 'username', user.username, 'firstName', user.firstName, 'last ...

js validating input from an HTML form causing errors

I am attempting to validate the input in two HTML input fields to ensure they only contain characters. If not, I want to display a message to the user. Here is my code using HTML and JavaScript: HTML: Player one name: <input type="text" id="firstna ...

What is the most effective method to verify the visibility of an element hidden by v-show when using testing-library in Vue?

When working with Vue and the testing-library, checking for the presence of an element in the DOM is straightforward. For instance, if the v-if condition for the element is set to false: element = screen.queryByTestId("my-element") expect(element).toBeNul ...

Passing a ref from a parent component to a child component in reactjs

I have the following situation, how can I make sure that the attachment field in the child component is accessible from the parent component? class ServiceDeskCustomerCreate extends Component { constructor(props, context) { super(props, context); ...