I want to have full control over the content of <input>
element.
With React, I can do that like:
import { useState } from "react";
function Form() {
const [value, setValue] = useState("");
const onSubmit = (event) => {
event.preventDefault();
// Do something with `value`
};
const onChange = (event) => {
const { value } = event.target;
// For example, users can type only uppercase letters
if (value === value.toUpperCase()) {
setValue(value);
}
};
return (
<form onSubmit={onSubmit}>
<input onChange={onChange} value={value} />
<button type="submit">Submit</button>
</form>
);
}
export default Form;
In Vue, however, I cannot control <input>
like:
<script setup>
import { ref } from "vue";
const value = ref("");
const onSubmit = () => {
// Do something with `value`
};
const onInput = (event) => {
// For example, users can type only uppercase letters
if (event.target.value === event.target.value.toUpperCase()) {
value.value = event.target.value;
}
};
</script>
<template>
<form v-on:submit.prevent="onSubmit">
<input v-on:input="onInput" v-bind:value="value" />
<button type="submit">Submit</button>
</form>
</template>
It looks Vue doesn't control the <input>
element's value
attribute and Vue's value
ref differs from value
in DOM.
How can I do the same thing as React in Vue? Thank you in advance.
CodePudding user response:
All you need is v-model
,
v-model
can do two-way binding with value
property and input
event.
So
<input
v-model="inputValue"
>
Is equal.
<input
:value="inputValue"
@input="event => inputValue = event.target.value"
>
So in you example you need.
<script setup>
import { ref } from "vue";
const inputValue = ref("");
const onSubmit = () => {
console.log(inputValue.value)
// Do something with `value`
};
</script>
<template>
<form v-on:submit.prevent="onSubmit">
<input v-model="inputValue" />
<button type="submit">Submit</button>
</form>
</template>
This is a live code example of what you are looking for.
https://stackblitz.com/edit/vue3-script-setup-with-vite-ze8fvb?file=src/App.vue
CodePudding user response:
If you bind a function to input
or change
events, the first parameter of the function is the event. If you want to prevent the event (that is, to prevent the change the user just attempted), all you have to do is call .preventDefault()
on the event
.
Documentation:
So, in your @change
or @input
handler, check whatever custom logic you want and, should you decide the change is not allowed, call .preventDefault()
on the event.
That being said, keep in mind it is generally a bad idea to call .preventDefault()
on user input. It's generally perceived as disrespectful. For example, checkouts using .preventDefault
have a lower conversion rate than the ones who tell user what's wrong with the input, without preventing the change. One could say .preventDefault
prevents sells on checkout pages.
A better idea is to allow the change and tell the user what's wrong with the current value.