Manual form input bindings in Vue.js
Tags: vue, webdev, tutorial, javascript
Published: 2022-05-04 22:33:53

When creating forms with Vue.js most of the times we' re using `v-model` for our form input bindings. `v-model` makes it super easy to sync the data model with our form fields' values and vice versa. 

It's the so called **two-way** binding.

There can be times though that we need more control on the field's value binding and this is when manual binding comes in.

## v-model under the hood
Vue.js documentation gives us a hint on how `v-model` works under the hood. It wire's up value bindings and change event listeners to the field element that is used on.

For example an `<input v-model="text">` translates to 
```html
<input
  :value="text"
  @input="event => text = event.target.value"
>
```

Here are the different DOM properties and event pairs for the basic form elements that we can leverage in order to recreate the `v-model` two-way binding manually using `v-bind` (`:`) and `v-on` ( `@`):

| Element      | Property | Event |
| ----------- | ----------- | ----------- |
| input    | :value  | @input |
| textarea | :value    | @input  |
| checkbox | :checked  | @change |
| radio    | :checked  | @change |
| select   | :value    | @change |

**Let's check how that looks in actual code**

## Manual binding examples

Although an [example](https://vuejs.org/examples/#form-bindings) for two-way form input bindings using `v-model` exists in the Vue.js docs site, there's no example on how to create the same bindings manually.

Let's see how we can create manual bindings for `checkbox` and `radio` as these are the most tricky to get right.

> At the end of this article you will find a [CodeSandbox](https://codesandbox.io/s/vue2-manual-form-bindings-cch9bh?file=/src/App.vue) that recreates the [Vue.js Form Bindings example](https://vuejs.org/examples/#form-bindings) using manual bindings. It also includes examples for manual binding multi-checkbox and multi-select lists.

### Checkbox
We usually bind a checkbox to a `boolean` value in our data model. Here's how to do that using manual binding.

```html
<input
  type="checkbox"
  :checked="booleanValue"
  @change="booleanValue = $event.target.checked"
/>
```

The key here is to `v-bind` the `checked` property and then assign the value back to the data model by reading the checkbox's `checked` attribute when the `change` event is fired.

> `$event` is a special variable that gives us access to the original DOM event inside the inline handler.

### Radio
When binding radio buttons we'll most likely use a text variable to hold the selected value. Manual binding works like this: We bind the `checked` property to the result of an expression that evaluates to whether the current selected value corresponds to that specific radio button. We read the selected value of the radio using the `change` event.

> Notice that we use `$event.target.value` as we need the actual text value.

```html
<input
  type="radio"
  value="One"
  :checked="textValue === 'One'"
  @change="textValue = $event.target.value"
/>

<input
  type="radio"
  value="Two"
  :checked="textValue === 'Two'"
  @change="textValue = $event.target.value"
/>
```

**More examples...**

You can check the [CodeSandbox here](https://codesandbox.io/s/vue2-manual-form-bindings-cch9bh?file=/src/App.vue:1150-1298) for detailed examples that also demonstrate how to bind multi-checkbox and multi-select lists.

It's good to know that manual binding works in **exactly** the same way in both [Vue.js 2](https://codesandbox.io/s/vue2-manual-form-bindings-cch9bh?file=/src/App.vue:1150-1298) and [Vue.js 3](https://codesandbox.io/s/vue3-manual-form-bindings-1ztxho?file=/src/App.vue).

Thanks for reading!