Vue.js — One-way Data Binding

Noctorus
Noctorus
Published in
3 min readFeb 8, 2019

By Noctorus

In the previous article, https://medium.com/@noctorus/beginning-vue-js-ef8879d2c394, we have briefly discussed how to jump start a Vue.js project.

Now, we’re going to discuss about one of the great feature in Vue.js, which set apart the methodology used in Angular v1.x, namely two way binding (and.

There are some other sources which briefly discuss the differences between these two and the pros and cons arises:

Let’s briefly discuss about these two methodologies.

Two Way Binding

please ignore the smiley from the image, it was taken from Angular website

Two way data binding means that UI fields are bound to model data dynamically such that when a UI field changes, the model data changes with it and vice-versa.

Example frameworks:

  • Angular v1.x

One Way Binding

please ignore the sad emoticon, it was taken from Angular website

One way data flow means that the model is the single source of truth.
Changes in the UI trigger messages that signal user intent to the model (or “store” in React). Only the model has the access to change the app’s state.

Effect for one way binding is that data always flows in a single direction, which makes it easier to understand.

Consider the following scenarios:

View-model Behavior

  • In web application, there is a text box (aka the view), and user is free to enter any value in it. You wouldn’t want the model value to be changed, as it would override the view value.
  • Example:
<template>
<div>
<input v-model="value" />
</div>
</template>
<script>
export default {
data () {
return {
value: 123
}
},
mounted () {
}
}
</script>

Parent-child relationship & single data source

  • Second example, modern JavaScript frameworks allowed us to create modular reusable components. Most of the time we would have parent-child components.
  • You only get to declare either one as the data source, and not both parents and child.
  • Any value changes in the parent model get reflected in the child, or vice versa but definitely it can’t be two way changes.
  • Parent as data source:
// ParentComponent.vue<template>
<div>
<child-component :valueChild="valueParent" />
</div>
</template>
<script>
import ChildComponent from '@/components/ChildComponent'
export default {
components: {
ChildComponent
},
data () {
return {
valueParent: 123
}
},
mounted () {
this.valueParent: 456
}
}
</script>
// ChildComponent.vue
// - model as props
// - data source from parent
<template>
<div>
<!-- <input v-model="valueChild" /> // not allowed to modify props -->
<input :value="valueChild" />
</div>
</template>
<script>
export default {
props: [
'valueChild'
],
data () {
return {
}
},
mounted () {
// this.valueChild: 456 // not allowed to modify directly
}
}
</script>
  • Child as data source:
// ParentComponent.vue
// - parent listen to value-changed event
<template>
<div>
<child-component @valueChanged="valueChanged" />
</div>
</template>
<script>
import ChildComponent from '@/components/ChildComponent'
export default {
components: {
ChildComponent
},
data () {
return {
valueParent: 123
}
},
methods: {
valueChanged: function (value) {
this.valueParent = value
}
},
mounted () {
}
}
</script>
// ChildComponent.vue
// - data source in child
<template>
<div>
<input v-model="valueChild" /><!-- use v-model directly -->
</div>
</template>
<script>
export default {
watch: {
valueChild: function (newValue, oldValue) {
this.$emit('valueChanged', newValue)
}
},
data () {
return {
valueChild: 123
}
},
mounted () {
this.valueChild = 456
}
}
</script>

In conclusion, it’s all depending on your needs to perform the intended behavior.

Feel free to try it out and structure your reusable components.

--

--