Using Vue component with v-model and custom input handler

I'm currently working on creating a wrapper component for an <input/> element in Vue.js.

Here is the component code:

<template>
  <div>
    <input v-bind="$attrs" :value="value" @input="input" />
    ...
  </div>
<template>

Vue.component("my-input", {
   inheritAttrs: false,
   props: ['value'],
   methods: {
     input($event): void {
       this.$emit("input", $event.target.value)
     }
  }
})

Usage example:

<my-input v-model="myModel" />

So far, everything seems to be functioning correctly. The model updates through the input event handler by emitting the value of the target element.

However, I encountered an issue when trying to integrate this component with existing code:

<my-input v-model="myModel2" @input="something = $event.target.value" />

The problem arises with the $emit("input") event. An error message stating "Cannot read property 'value' of undefined" is displayed.

This means that the $emit function is emitting the value separately, causing difficulties for the existing @input="something..." event handler to access the $event properly.

If the component's input method is modified to emit the entire $event instead of just $event.target.value, the new code functions as intended. However, the model now captures the InputEvent rather than the actual value.

At this point, I am uncertain about the next steps needed to resolve this dilemma.

Answer №1

When triggering $emit('input') and linking it to a v-model of a text input, the value in the input field will be updated based on what you emitted. Specifically, when using

$emit('input', $event.target.value)
, the emitted value will be the text within the input field itself. The parent component will then intercept this value because that is what v-model essentially does:
<my-input :value="inputValue" @input="inputValue = $event">

In essence, this results in binding the value of the <input> back to the same <input> (thereby maintaining the current value). On the other hand, if you were to $emit('input', $event), v-model would still capture and update the input value with whatever data is passed up, which, in this case, would be the actual input event object as specified.

If you prefer not to utilize the default input event linked to your model, an alternative approach could involve creating a custom v-model event. This way, by emitting $emit('input', $event), you can have the value affected without impacting the v-model's value. Instead, you could update the v-model through

$emit('custom-event', $event.target.value)

Answer №2

Experiment

<special-input v-model="specialModel2" @input="data => another = data" />

Answer №3

Instead of creating proxies, directly assign them from the parent

const MyInput = Vue.extend({
  name: 'MyInput',
  template: '#ins',
  data(){return{valid: true}},
  methods: {validate(ev){this.valid = ev.target.value.length < 1 ;this.$listeners.input(ev)}}
})

const App = Vue.extend({
  components: {
    MyInput
  },
  template: '#myinput',
  data(){return{val: 'test'}},
  methods: {ins(ev){console.log(ev.target.value)}}
})

new Vue({
  name: 'root',
  render: h => h(App)
}).$mount("#app");
input {background: red}
.valid{background:green !important}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app"></div>

<template id="ins">
  <input v-bind="$attrs" @input="validate" :class="{valid:valid}"/>
</template>

<template id="myinput">
    <my-input v-model="val" @input="ins" />
</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

How can I force a Kendo UI Chart to resize in VueJS?

When integrating Kendo UI's Chart component within a Vue application, how can we trigger the chart to refresh or redraw? Although the chart automatically adjusts to changes in width by filling its parent container horizontally, noticeable stretching ...

Unable to modify an attribute due to TypeScript error: Type 'string' cannot be assigned to type 'never'

I am trying to modify an attribute of an object in TypeScript and React, but I keep encountering the following error message: Type 'string' is not assignable to type 'never'. This happens even though I have a check in place to verify th ...

Error occurs in Javascript when attempting to execute javascript code using PHP's echo and an unexpected identifier token is encountered

Currently, I am trying to insert a div into the page when a specific condition is met in PHP: if ($var == 0) { echo '<script>console.log("Test."); var res = document.getElementById("response"); res.innerHTML = "<div class='h ...

Choose a minimum of one validation for the list item

When I have a form in JSP that includes a drop-down view with multiple options, I want to ensure that at least one option is selected before the form can be submitted. If no options are selected, the form should not be able to submit. Thank you in advance ...

The HTTP response object in Express does not provide any data in its return

While working on developing a server using express js, I encountered an issue. When I send a get request to my endpoint from another server, the response is received successfully; however, it does not contain the data that was sent by the server after res. ...

Comparing Objects in an Array to Eliminate Duplicates and Make Updates in Javascript

I am working with an array of objects that is structured like this: 0: Object ConsolidatedItem_catalogId: "080808" ConsolidatedItem_catalogItem: "undefined" ConsolidatedItem_cost: "0" ConsolidatedItem_description: "Test Catalog Item" ConsolidatedItem_ima ...

Only perform the Rails ajax call once initially

I'm currently working on creating a drop down menu that contains a substantial amount of content, and I would like to use an ajax get call to load everything upon mouse enter. Here is my code written in coffeescript: class @SecondaryMenu construct ...

Guide on integrating jQuery list filtering in Ionic 2

I stumbled upon a jQuery function that filters data in HTML, found it online. Now, I want to incorporate a similar feature into my Ionic app. However, I am unsure about the modifications required in list-search-min.js. Here is a snippet of my index.html: ...

Employ a variable within the fetch method to retrieve JSON data

Currently, I am in the process of developing a system that extracts specific information from a JSON file based on user input. One challenge that I am facing is how to incorporate a variable into the designated section of my code; fetch( ...

Utilizing React Router DOM 6.3.0 to read the pathname from an undefined source

I am currently using react-router-dom version 6.3.0 and have set up the following routes inside my App component <BrowserRouter> <Routes> <Route path='/article/*' element={<Article />} /> </Routes> </Brows ...

Tips on integrating Codrops tutorial codes into a SilverStripe website project

Exploring the vast array of tutorials and code examples on the Codrops site has been an enlightening experience. Codrops Website I'm eager to incorporate some of these resources into my SilverStripe projects as well. SilverStripe CMS After learning h ...

Limiting Node.js entry with Express

I have a node.js script running on a server. I want to prevent it from being accessed directly from a browser and restrict access to only certain domains/IP addresses. Is this achievable? ...

Removing an element with a specific class that was created with Javascript can be done by clicking outside the box

I needed to eliminate an element that was created using JavaScript of a specific class when clicked outside the box. I have created a color-picker using .createElement and added a class to it. Now, my goal is to remove that picker whenever a click occu ...

Unexpected Error: Unable to access the 'position' property of an undefined element (D3.JS)

This error occurred when I attempted to fetch JSON data and convert it into a line graph. An unexpected TypeError was thrown: Unable to access the 'position' property of undefined Below is the relevant portion of the JS code: d3.json("../js/ ...

Using JavaScript to Filter Arrays with Partial String Matching

I have an array of objects where the value I need to filter on is nested in a lengthy string. The array is structured as follows: { "data": { "value": & ...

Create-react-app fails to generate a template even though the react framework is fully updated

I attempted to set up a fresh react directory using npx create-react-app. Unfortunately, every solution I tried resulted in the template not being provided, with the common suggestion being that my version of create-react-app may be outdated. I verified t ...

Boost Engagement with the jQuery PHP MySQL Like Feature

Seeking assistance in creating a like button with PHP, MySQL, and jQuery. I'm encountering an error but unable to pinpoint its source. Can anyone provide guidance? The project involves two pages: index.php & callback.php INDEX $k = 1; //POST ID $n ...

Ways to eliminate class from HTML code

Trying to detect if a navigational element has a specific class upon click. If it has the class, remove it; if not, add it. The goal is to display an active state on the dropdown button while the dropdown is open. The active state should be removed when a ...

Is there a way to streamline this JavaScript Defer code?

I am currently managing a JavaScript bootstrapper module that I want to keep as clean and straightforward as possible. Here is the current code snippet: function bootStrapper() { xmlRepository.getAll().done(function (result) { autoPolicyForm ...

Generating npm package without including file extensions in imports

I am currently working on creating an internal library for my workplace. Everything seems to be going smoothly until I try to use it in another project. It appears that the file extension in all of the import statements has disappeared during the npm pack ...