Svelte Series-4: Two-Way Binding
Tags: svelte, frontend, framework, javascript
Published: 2024-05-22 13:39:00

## MVVM

Currently common software development architecture patterns are MVC, MVP, MVVM.   
Among them MVC (Model-View-Controller) is divided into three parts:

- M (Model): responsible for managing the application data
- V (View): mainly corresponds to the application of the user interaction page
- C (Controller): receives the data passed in from the user interface and calls the corresponding controller to update the data. When the data is updated, it will trigger the update of the page.

![MVC](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fvwv2lshdb0gqhnckcx1.png)

The other architectural pattern, MVVM, is also divided into three parts:
- M (Model)
- V (View)
- VM (ViewModel): Responsible for exposing the model's data and commands so that the view can use them.

![MVVM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u98ateb7sj2tujn6xjt3.png)

Two-way data binding is where data changes drive view updates, and view updates trigger data changes; both Vue and Svelte support it. In Vue, we use `v-model` to implement two-way data binding. Since Svelte is so convenient to manipulate the data, you may think that we write this code directly, and then Svelte can handle two-way binding for us.

```html
<script>
  let str = ''
</script>

<div>
  <input type="text" value={str} />
  <span>input value: {str}</span>
</div>
```

Unfortunately, the above code doesn't handle two-way binding for us, if we want to do two-way binding, we need to write it as below:
```html
<script>
  let str = ''
</script>

<div>
  <input type="text" bind:value={str} />
  <span>input value: {str}</span>
</div>
```

Notice the difference? That's right, we need to use `bind`, which has other uses besides two-way binding, and which we'll continue to use in later chapters.

### Two-way binding in form component

```html
<script>
  let value = '';
</script>

<input type="text" value={value} />
<p>value: {value}</p>
```

If we follow the logic of Vue and write the above code directly, we will find that when we fill in the content in the input box, the output is not followed on the page.

```html
<script>
  let value = '';
</script>

<input type="text" value={value} on:input="{e => value = e.target.value}" />
<p>value: {value}</span>
```

#### `input[type="text"]`
```html
<script>
  let value = '';
</script>

<input bind:value={value} />
<p>value: {value}</p>
```

#### `input[type="number"]`
```html
<script>
  let value = 1;
</script>

<input type="number" bind:value={value} />
<input type="range" bind:value={value} min={1} max={5} />
```

#### `input[type="checkbox"]`
```html
<script>
  let checked = false;
</script>

<label>
  <input type="checkbox" bind:checked={checked} />
  select: {checked}
</label>
```

#### `input[type="radio"]`
```html
<script>
  let radioValue = "";
</script>

<label>
  <input type="radio" bind:group={radioValue} value={1} />
  1
</label>

<label>
  <input type="radio" bind:group={radioValue} value={2} />
  2
</label>

<label>
  <input type="radio" bind:group={radioValue} value={3} />
  3
</label>

<p>chosen: {radioValue}</p>
```

#### `bind:group`
```html
<script>
  let checkboxValue = [];
</script>

<label>
  <input type="checkbox" bind:group={checkboxValue} value={1} />
  1
</label>

<label>
  <input type="checkbox" bind:group={checkboxValue} value={2} />
  2
</label>

<label>
  <input type="checkbox" bind:group={checkboxValue} value={3} />
  3
</label>

<p>chosen: {checkboxValue.join(',')}</p>
```

#### `select`
```html
<script>
  let selectValue;
</script>

<select bind:value={selectValue}>
	<option value={1}>1</option>
	<option value={2}>2</option>
	<option value={3}>3</option>
</select>

<p>chosen: {selectValue}</p>
```

In addition to the components listed above that enable bidirectional binding, Svelte also supports bidirectional binding of many elements, such as textarea, media tags video, audio, etc.

### Two-way binding in custom component
```html
<script>
  export let value;
</script>

<input bind:value={value} />
```
Here we encounter a new keyword, `export`, which we'll cover in the next chapter.

```html
<script>
  import Child from './Child.svelte';
  let fatherValue = ''
</script>

<Child bind:value={fatherValue} />
<input bind:value={fatherValue} />
```

## Brief Summary

In this chapter we have learned:
- Using `bind` in Svelte to implement two-way data binding for form type components.