'How to use v-model on component in vue 3 script setup
I want to add a v-model
on a component but I got this warning:
[Vue warn]: Component emitted event "input" but it is neither declared in the emits option nor as an "onInput" prop.
Here is my code:
// Parent.vue
<template>
<h2>V-Model Parent</h2>
<Child v-model="name" label="Name" />
<p>{{ name }}</p>
</template>
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
const name = ref('')
</script>
// Child.vue
<template>
<input
class="input"
type="text"
:placeholder="props.label"
:value="props.value"
v-on:input="updateValue($event.target.value)"
/>
</template>
<script setup>
import { defineProps, defineEmit } from 'vue'
const props = defineProps({
label: String,
value: String
})
const emit = defineEmit('input')
function updateValue(value) {
emit('input', value)
}
</script>
I was trying to reproduce this tutorial but I'am stuck and got no idea what I am missing.
I want to display {{ name }}
in the Parent.vue component. Do you got an idea how to solve this?
Solution 1:[1]
In vue 3 value
prop has been changed to modelValue
and the emitted event input
to update:modelValue
:
// Child.vue
<template>
<input
class="input"
type="text"
:placeholder="props.label"
:value="props.modelValue"
v-on:input="updateValue($event.target.value)"
/>
</template>
<script setup>
const props = defineProps({
modelValue: String
})
const emit = defineEmits(['update:modelValue'])
function updateValue(value) {
emit('update:modelValue', value)
}
</script>
Solution 2:[2]
I like to use with computed as well
<template>
<div>
<input v-model="model">
</div>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
modelValue: {
type: [String, Number],
default: ''
}
})
const emit = defineEmits(['update:modelValue'])
const model = computed({
get () {
return props.modelValue
},
set (value) {
return emit('update:modelValue', value)
}
})
</script>
Solution 3:[3]
I have the similar issues and finally I got it work. Here are one solution for one or multiple checkbox for Vue 3 and TypeScript.
solution : for one or multiple checkbox
CheckBox Component:
<template>
<input
type="checkbox"
:value="inputValue"
:disabled="isDisabled"
v-model="model"
:class="[defaultClass, inputClass, checkboxClass]"
/>
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue';
export default defineComponent({
components: {},
props: {
inputValue: {
type: String,
required: false,
default: '',
},
modelValue: {
type: [Object, Boolean] as PropType<String[] | Boolean>,
required: false,
default: (() => ({})) || false,
},
isDisabled: {
type: Boolean,
required: false,
default: false,
},
checkboxClass: {
type: String,
required: false,
default: '',
},
},
data() {
return {
defaultClass: 'h-4 w-4 rounded text-primary shadow-sm',
};
},
emits: ['update:modelValue'],
computed: {
model: {
get() {
return this.modelValue;
},
set(value) {
this.$emit('update:modelValue', value);
},
},
inputClass() {
if (this.isDisabled) {
return 'bg-dark-17 border-dark-13';
}
return 'bg-dark-23 border-dark-10 hover:bg-dark-25 focus:border-primary';
},
},
});
</script>
import CheckBox and use it
import CheckBox in other components;
<div>
<div v-for="(option, index) in options" :key="index">
<div
class="flex items-center justify-between p-6 py-4 border-b border-b-dark-13"
>
<div class="w-10">
<Checkbox :inputValue="option.name" v-model="selectedOptions" />
</div>
</div>
</div>
</div>
data() {
return {
selectedOptions: [],
};
},
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Douglas Calora |
Solution 3 | sherwin water |