With Vue3 we can use multiple definitions of v-model.
In the example 2 v-model definitions are implemented on a custom component.
in the Parent:
<template>
<label>Message</label>
<CustomInput
v-model:input="message"
v-model:valid="isMessageValid"
:validator="validate"
/>
</template>
<script>
import CustomInput from './CustomInput.vue';
export default {
components: {
CustomInput
},
data() {
return {
message: '',
isMessageValid: false
};
},
methods: {
validate(input) {
return !!input;
}
}
};
</script>
in custom component:
<template>
<input
type="text"
v-model="inputValue"
@input="setValidity"
/>
{{ validValue }}
</template>
<script>
import { computed } from 'vue';
export default {
props: {
input: {
type: String
},
valid: {
type: Boolean
},
validator: {
type: Function,
required: true
},
},
setup(props, { emit }) {
const inputValue = computed({
get: () => props["input"],
set: (value) => emit("update:input", value)
});
const validValue = computed({
get: () => props["valid"],
set: (value) => emit("update:valid", value)
});
return {
inputValue,
validValue,
};
},
methods: {
setValidity() {
this.validValue = this.validator(this.input);
}
}
};
</script>
In Vue2 only 1 v-model definition is allowed:
<template>
<label>Please select one</label>
<div>
<div
v-for="(option, index) in options"
:key="index"
@click="selectOption(option)"
>
{{ option }}
</div>
</div>
</template>
<script>
export default {
props: {
value: {
type: String,
required: true
}
},
data() {
return {
options: ["Choice 1", "Choice 2", "Choice 3"]
};
},
methods: {
selectOption(option) {
this.$emit("update:modelValue", option);
}
}
};
</script>
- value prop is required to use v-model.
- The event update:modelValue has to be emitted to change the the value (naming is important).