I'm trying to create custom Input component with composition API in Vue 3 but when I'm trying to update value with v-model I am getting empty string instead of event value and when I replace custom Input
component with default HTML input
the value is being updated as expected
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>
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 };
},
There are a couple of errors & warnings in your code:
emits
option ( more on this here )value
prop passed down from the parent component to Input
(thus I removed it)v-model
, then it's best to emit a custom event called update:modelValue
(where modelValue
is the value you want to bind as prop, eg update:name
; more on this here )setup
function the same as a prop
(this is just sensibility - you'll mess up what is what, eventually) 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>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.