Vue computed getters and setters
I figured out I’d post a short note about a feature I find very useful with Vue computed properties.
Have you ever been in a situation where you need to integrate a third-party component which emits data in a very inconvenient format for your application? Let’s say that you’ve got a location fetcher component that exposes a lot of data:
{
latitude: 44.427998,
longitude: 26.098756,
city: "Bucharest",
country: "Romania"
}
Let’s say that your component is deeply nested and it only needs to emit country
and city
to the outside, while also ignoring the rest of the noise (note: I’m using JSX for writing Vue components here, which may look a bit strange). One more requirement is it also needs to pass the country
and city
back to the third party component, just to complicate things a bit.
import ThirdPartyLocationFetcher from './ThirdPartyLocationFetcher.js'
export default {
name: 'DeeplyNestedComponent',
props: ['map_data'],
render() {
return (
<div>
<ThirdPartyLocationFetcher
// Pass just the filtered data somehow
map_data={...}
onInput={unfilteredData => {
// Filter and emit a new event
}}
/>
</div>
)
},
}
A very neat solution for this problem is to create a computed property with a custom setter and getter. In short, this is very useful when you need to have intermediate representations of other, more complex, values. They have a very short lifespan and they’re very easy to reason about. Setters and getters just get the job done, without asking too much. A very extensive documentation on those can be find on vuejs.org website. Here I’m going to show how to solve our little problem with them:
export default {
name: 'DeeplyNestedComponent',
props: ['map_data'],
computed: {
filteredMapData: {
set({ country, city }) {
this.$emit('newMapData', { country, city });
},
get() {
return this.map_data;
},
},
},
render() {
return (
<div>
<ThirdPartyLocationFetcher
map_data={this.filteredMapData}
onInput={(unfilteredData) => (this.filteredMapData = unfilteredData)}
/>
</div>
);
},
};
Here we filter just the needed part, using ES6 arguments destructuring and just pass the resulting data up the events chain. Below I’m having a complete but very simplistic demo using this technique.
Make sure to check out src/components/DeeplyNestedComponent.js
file.
Simple and gets the job done. Now you can go home, take a rest.
Andrei Glingeanu's notes and thoughts. You should follow him on Twitter, Instagram or contact via email. The stuff he loves to read can be found here on this site or on goodreads. Wanna vent or buy me a coffee?