Simplify Your Vue Components with Computed Setters

Taha Shashtari
Dec 10, 2018 · 2 min read

One of the main core concepts of Vue.js is computed properties. With computed properties, we can easily compose new data that is derived from other data. And that new data will be cached until one of its dependencies changes.

Here’s a quick example on that:

data () {
return {
firstName: 'Foo',
lastName: 'Bar'
}
},

computed: {
fullName () {
return `${this.firstName} ${this.lastName}`
}
}

fullName is what we call a computed getter — we use it to get the computed value. But what if we also want to set it?

We can define a computed setter for that, like this:

computed: {
fullName: {
get () {
return `${this.firstName} ${this.lastName}`
},
set (fullName) {
this.firstName = fullName.split(' ')[0]
this.lastName = fullName.split(' ')[1]
}
}
}

Now, whenever you set a new value to fullname (using this.fullName = 'Example Name'), firstName and lastName will update accordingly.

Show me a practical example

When your component is using data from outside — like data passed via props or from vuex — you can simplify the way you interact with this data using computed setters.

Let’s take an example that at first doesn’t use computed setters, and then improve it by introducing computed setters to it.

Without computed setters:

<template>
<div>
<input
:value="text"
type="text"
@input="onInput"
>
<button @click="convertToUpperCase">ToUpperCase</button>
</div>
</template>
<script>
export default {
props: ['text'],
methods: {
onInput (e) {
this.$emit('set-text', e.target.value)
},
convertToUpperCase () {
this.$emit('set-text', this.text.toUpperCase())
}
}
}
</script>

With computed setters:

<template>
<div>
<input
v-model="textValue"
type="text"
>
<button @click="convertToUpperCase">ToUpperCase</button>
</div>
</template>
<script>
export default {
props: ['text'],
computed: {
textValue: {
get () {
return this.text
},
set (value) {
this.$emit('set-text', value)
}
}
},
methods: {
convertToUpperCase () {
this.textValue = this.textValue.toUpperCase()
}
}
}
</script>

Using computed setters improved our example in two ways:

  1. First, updating the external data feels much simpler. We now can replace :valueand @input with v-model. Also we can change the value with a simple assignment — like what we have in convertToUpperCase method.
  2. Second, changing the source of the external data only requires updating the computed setter as opposed to replacing each $emit('set-text') in the component. So if you decided to change the source to using data from vuex, you would just need to change the setter method to something like this.$store.dispatch('SET_TEXT', value).

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store