Exploring Vue.js: Reactive Two-Way Data Binding

One of the core features of Vue.js is it’s reactive data binding system. In simple terms: it keeps your data (i.e. your Javascript variables, arrays etc) in sync with your DOM without you having to do anything.

In our last story we showed an example of how Vue will reactively update your DOM when a variable’s value is changed. Here’s a another simple example:

<div id="app">
<span>{{message}}</span>
</div>
<script type="text/javascript">
var message = 'Vue.js is rad';
new Vue({ el: '#app', data: { message } });
</script>
// Changing the value of message in the JS to something else 
// will be reflected automatically in the DOM. Nice.

Two-way data binding

Okay, so that’s one-way data binding i.e. binding a JS variable to the DOM. Two-way binding is when data is also bound from the DOM back to JS.

For example, what if we could change the value of message in the DOM via an input? No problemo. Just add an input to the document with an attribute v-model and assign it our message property i.e.:

<div id="app">
<span>{{message}}</span><br/>
<input v-model="message">
</div>
<script type="text/javascript">
var message = 'Vue.js is rad';
new Vue({ el: '#app', data: { message } });
</script>

That’s it. Nothing else. Now, if we type anything into our input, our JS variable is updated with the change, which in turn updates our span. Super nice.

Directives

The attribute v-model is a Vue directive. A directive’s job is to reactively apply special behaviour to the DOM when the value of its expression changes. In the case of v-model, it binds the element to one of the data properties that Vue is watching.

We’ll look at some other directives in coming stories e.g. v-on which binds an element to an event e.g. v-on:click…I’m sure you can guess what that does.

Reactive two-way binding with jQuery

You can two-way binding in jQuery or plain JS as well. It’s good to think about how you’d do that so you get a sense of what Vue is doing for you.

<input id="input" type="text">
<br>
This is the message: <span id="output"></span>
<script type="text/javascript">
var $input = $('#input');
var $output = $('#output');
  // A controller for getting/setting the bound variable
var message = {
content: null,
get: function() {
return this.content;
},
set: function(val) {
this.content = val;
$output.html(val);
$input.val(val);
}
};
  // Listens for changes in input
$input.on("keyup", function() {
message.set($(this).val());
});
  message.set('jQuery data binding is far less sexy.');
</script>

TL;DR: use an event listener to listen for changes in the input e.g. keyup. You’ll need to make your own logic for reactively updating the DOM when your variable changes. This can be done by using a custom getter/setter on your variable.

You can achieve reactive data binding in jQuery, but it’s just a sideshow. In Vue, it’s the main event.

We go through a complete example of setting up two-way binding in Vue in this video:

Next time…

In the next story we’ll be looking at binding arrays. Imagine if you could add/remove from an array in JS and have this automatically modify a ul in your DOM…