The custom input element in Composition API fails to update its value

I am currently working on creating a custom Input component using Vue 3's composition API. However, I encountered an issue where updating the value with v-model resulted in receiving an empty string instead of the expected event value. Surprisingly, when I swapped out the custom Input component with the default HTML input, the value was updated as intended.

This is the code for the Input component:

<template>
  <input
    :type="type"
    :id="name"
    :name="name"
    :placeholder="placeholder"
    class="input"
    v-model="modelValue"
  />
</template>

<script lang="ts">
import { computed } from 'vue';

export default {
  name: 'Input',
  props: {
    modelValue: {
      type: String,
      required: true,
    },
    name: {
      type: String,
      required: true,
    },
    type: {
      type: String,
      default: 'text',
    },
    placeholder: {
      type: String,
      required: true,
    },
  },
  setup(props: { value: string }, { emit }) {
    const modelValue = computed({
      get() {
        return props.modelValue;
      },
      set(value) {
        emit('input', value);
      },
    });

    return { modelValue };
  },
};
</script>
<form @submit.prevent="handleSubmit">
     <Input :name="name" placeholder="Name*" v-model="name" />
     <Button>Send</Button>
</form>

This is the setup method:

  setup() {
    const name = ref('');

    function handleSubmit(data: Event) {
      console.log(data, name.value);
    }

    watch(name, (old, newValue) => {
      console.log(name, old, newValue);
    });

    return { name, handleSubmit };
  },

Answer №1

There are a few mistakes and warnings in your code:

  • You need to specify emitted events in the emits option (learn more about this here)
  • A value prop was not passed from the parent component to Input, so I removed it
  • If you want to use v-model for easy synchronization, emit a custom event named update:modelValue (where modelValue is the value to bind as prop; e.g. update:name; more information here)
  • Avoid naming variables in the setup function the same as a prop to prevent confusion and errors

const {
  computed,
  ref,
} = Vue

const Input = {
  name: 'Input',
  props: {
    name: {
      type: String,
      required: true,
    },
    type: {
      type: String,
      default: 'text',
    },
    placeholder: {
      type: String,
      required: true,
    },
  },
  emits: ['update:name'],
  setup(props, { emit }) {
    const modelValue = computed({
      get() {
        return props.name;
      },
      set(value) {
        emit('update:name', value);
      },
    });

    return {
      modelValue
    };
  },
  template: `
    <input
      :type="type"
      :id="name"
      :name="name"
      :placeholder="placeholder"
      class="input"
      v-model="modelValue"
    />
  `
}

const App = {
  setup() {
    const name = ref('');

    function handleSubmit(data) {
      console.log(data, name.value);
    }

    return {
      name,
      handleSubmit
    };
  },
  template: `
  Name Ref: {{ name }}<br />
  <form @submit.prevent="handleSubmit">
    <Input
      :name="name"
      placeholder="Name*"
      v-model="name"
    />
    <button type="submit">Send</button>
  </form>
  `
}

const vm = Vue.createApp(App)

vm.component('Input', Input)

vm.mount('#app')
<script src="https://unpkg.com/vue@next"></script>

<div id="app"></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

Custom AngularJS Directive for managing an array of Scope data

I have an array where each item contains data for a specific directive. This array is initialized within a controller. The Model $scope.myDirectiveData = [ { title: "First title", content: "First content" }, { title: "Second title ...

Electron / Atom Shell unable to locate specified module

I am completely new to npm, node, and Electron. Here is the structure of my folder: -package.json -index.html -main.js -js/myStuff.js -node_modules In the file myStuff.js, I have a line that says var chokidar = require('chokidar'); but it keep ...

Unleashing the Power of Object Destructuring in React Hooks

Here is a straightforward code snippet: import React from "react"; import { useForm } from "react-hook-form"; export default function App() { const { register, formState: { errors }, handleSubmit } = useForm(); return ( < ...

Executing a JavaScript code on a Node.js server involves running the script through the Node

I have developed a node.js server and successfully extracted the HTTP POST and GET variables from the request. Now, I want to pass these variables to a JavaScript script on the server for execution. In PHP, this can be easily achieved by pointing to the sc ...

Enhancing Vue app with durable storage capabilities

Currently, I am delving into VueJS and have created a basic todo application. It functions effectively, but my goal is to save data locally so that it remains persistent even after the page is reloaded. The code below is a result of following some helpful ...

Enclosing values in JavaScript literals

I apologize for the inconvenience. I am unsure why it is not functioning properly. If I input <button type="button" onclick="document.getElementById("demo").innerHTML = Date()">click</button> the above code does not work. However, if I u ...

Encountering difficulties in sending a POST request using HTTP in Angular 4

While working on a small Angular frontend with REST api support in the backend, I encountered a peculiar issue. When attempting to execute http.post(url, data, params), nothing seems to happen. There are no signs of the request reaching the webserver, and ...

Utilizing Lodash to transform an array into a new array based on single-character values

I am working with an array that consists of various objects, such as: var people = [{ _id: 0, name: 'Joe' }, { _id: 1, name: 'Jim' }, { _id: 2, name: 'Mary' }]; Using lodash, I am looking to extract e ...

"Hey, do you need a see-through background for your

Currently, I am implementing the JS library found at . Unfortunately, I am struggling to make the background transparent or any other color. It appears that the issue lies in the fact that the tab styles are being overridden by the JS library whenever the ...

Verify if the ajax request does not contain any data

Utilizing the complimentary geocoding API provided by MapQuest I'm attempting to verify the success of a request that returned no data. Entering "vdfsbvdf54vdfd" (a nonsensical string) as an address in a form field, I anticipate receiving an alert s ...

JavaScript: changing text to numbers within an array

Looking at this array of strings: ["5:17", "8:22", "3:34", "5:23", "7:12", "7:24", "6:46", "4:45", "4:40", "7:58", "11:51", "9:13", "5:50", "5:52", "5:49", "8:57", "11:29", "3:07", "5:59", "3:31"] I'm curious, how do you suggest converting the ...

Mongoose: No documents are being returned by the .find() method

UPDATE : Similar question posted here: Trouble with Mongoose find() method I'm still new to working with nodejs and nosql databases. Today, I am building an API that retrieves data from my user collection which currently has two entries : https://i. ...

Updating a computed property in Vue.js after an asynchronous computed property has been updated

I'm currently facing an issue with updating a computed property (filteredSyms) that relies on an asynchronous computed property (allSynonyms). To handle this, I am utilizing the async-computed plugin available at: https://www.npmjs.com/package/vue-as ...

Error in React JS: SyntaxError - "Unexpected token '?'"

Following the guidelines on this website, I successfully set up a new reactJS application, proceeded to run npm i && npm run dev and encountered the following error message: /home/www/node_modules/next/dist/cli/next-dev.js:362 showAll ...

The return value of fs.mkdirSync is undefined

I'm facing a challenge with creating a directory and utilizing that directory as a variable to extract files from zip/rar files. The section of code that is causing an error is shown below: var fileZip = fileName.replace(/^.*[\\\/]/, ...

How to set cells to plain text in google sheets

I've been grappling with a formatting issue that I'm hoping someone can assist me with. In my script, there's a point where I need to combine the date value (e.g., 11/20/2020) from one column with the time (3:00 PM) from another column. This ...

Modify URL parameters using history.pushState()

Utilizing history.pushState, I am adding several parameters to the current page URL after performing an AJAX request. Now, based on user interaction on the same page, I need to update the URL once again with either the same set of parameters or additional ...

Transforming a directory structure into JSON using Node.js

Looking to Achieve: My aim is to transform the existing directory structure provided below into a single JSON file. The directory includes JSON files that must be integrated into the output file. Restrictions: Only Node.js Inquiries: How can I effi ...

When changing the dropdown option on a separate page in React/Next JS, all checkboxes show the clicked style as a result of utilizing useState

I have implemented checkboxes for three different categories: "Types", "Price", and "Categories". They function correctly, with data being passed to a separate checkbox component without any issues. The problem arises when I click a checkbox and then inte ...

Learn how to retrieve a meta tag's content value and perform a subtraction operation

I need assistance in retrieving the value of the meta tag content and performing a subtraction operation on it. Could someone lend me a hand with this, please? The meta tag is structured as follows: <meta itemprop="price" content="1699"> I ha ...