ES6 was a big step forward for the web, and it introduced many new features that solve various pain points that exist for all JavaScript developers. But a few of its features are specifically suited to solve problems that arise when developing with Vue.js. This article will cover four of those Vue-specific features. We’ll look at how each feature works and what problem it solves for your apps and websites. Without further ado, let’s dive in!
Feature #1: Method definition shorthand
This first feature I want to talk about has a purely aesthetic effect, but it really helps to make your code as readable as possible. ES6 introduced this shorthand to more succinctly assign functions to objects, which we do all the time in Vue for methods, computed properties, watchers, and lifecycle methods. Here’s an example of how you can apply it to your Vue code:
// Without shorthand
{
methods: {
getValue: function() { // ... }
},
computed: {
halfValue: function() { // ... }
},
created: function() { // ... }
}
// With ES6 shorthand
{
methods: {
getValue() { // ... }
},
computed: {
halfValue() { // ... }
},
created() { // ... }
}
Again, this is a small change, but it can make a big difference for readability.
Feature #2: Destructuring
Destructuring is a feature added in ES6 that makes it easier to pull properties out of an object and assign them to a variable. Before we get into how this helps us in our Vue code, here’s a very basic example of how object destructuring works:
const person = { name: 'Jake', email: 'jake@example.com', phone: '555-555-5555' }
// With destructuring
const { name, email, phone } = person
// Without destructuring
const name = person.name
const email = person.email
const phone = person.phone
The two examples above (with/without destructuring) work exactly the same. The version using destructuring is just a cleaner code pattern to achieve the same result.
So how can you use destructuring in your Vue codebases? There are two main areas where destructuring shines in Vue: destructuring properties from this
, and receiving props from scoped slots. Let’s walk through each of those use cases.
Destructuring from this
In Vue, to reference data, methods, or anything on the Vue or your component instance, you use this
. But sometimes it’s nice to access those instance properties without referring to this
over and over again. Let me show you a nice little trick to pull properties from this
into your local function scope:
data() {
return {
endpoint: 'example.com/api',
}
},
methods: {
postForm() { // this is just an example method we can call in submitForm }
submitForm() {
// Without destructuring
const endpoint = this.endpoint
const postForm = this.postForm
// With destructuring
const { endpoint, postForm } = this
}
}
This pattern allows us not only to use these variables without the this
prefix, it also gives us clarity on which pieces of data and/or methods that our function relies on.
Scoped slots
Slots allow us to pass templates into our components, and scoped slots allow our components to provide some component data to those templates. If you’re not familiar with scoped slots, this might not make as much sense, but hopefully this example can at least reinforce how destructuring works and how you can use it in many different scenarios:
<!-- Without Destructuring -->
<User v-slot="slotProps">
<div>Name: {{ slotProps.name }}</div>
<div>Email: {{ slotProps.email }}</div>
</User>
<!-- With Destructuring -->
<User v-slot="{ name, email }">
<div>Name: {{ name }}</div>
<div>Email: {{ email }}</div>
</User>
Not unlike the “destructuring from this
” pattern, not only does destructuring our slot props allow us to access our variables without using the slotProps
prefix, but it shows us exactly what properties we are accepting through the slot.
Feature #3: Functional array methods
ES6 introduced many new methods built into the Array prototype. These methods allow you to interact with the data in your arrays in different ways, like transforming each item (map
), sorting an array, or filtering an array. My favorite array methods that I use commonly in Vue apps are filter
, map
, forEach
, and includes
. Here’s an example using filter
:
computed: {
// Without "filter" functional array method
oldFilteredItems() {
const filtered = []
for (const item in this.items) {
if(item.value > 10) {
filtered.push(item)
}
}
return filtered
},
// With "filter" functional array method
filteredItems() {
return this.items.filter((item) => item.value > 10)
}
}
This reduces the code we have to write (and read!) from seven lines to only one!
Feature #4: Arrow functions
Before we learn about arrow functions, how they work, and how to use them in your Vue code, let’s look at the problem they solve. Check out the following code:
data() {
return {
scrolled: false
}
},
mounted() {
window.addEventListener('scroll', function() {
this.scrolled = true
})
}
This code doesn’t work. Why? Because when you create a new function, the value of this
is re-bound to equal the function instance instead of the Vue instance. If you’ve ever run into this problem, you may have tried the following approach to fix this problem:
mounted() {
var self = this
window.addEventListener('scroll', function() {
self.scrolled = true
})
}
While this does “fix” the problem, it is definitely not ideal to have var self = this
littered around your code, especially when this is a solvable problem with (drumroll please) … arrow functions!
Arrow functions are very similar to standard functions, but one key difference is that arrow functions don’t re-bind this
, which is very helpful in Vue apps! Here’s an updated version of the earlier example, wherein we’ve replaced the standard function with an arrow function so this
doesn’t get re-bound:
mounted() {
window.addEventListener('scroll', () => {
this.scrolled = true
})
}
Here is a rule that I find helpful to follow when writing Vue apps: within Vue components, this
should always refer to the Vue instance. This isn’t hard to achieve if you use arrow functions, and it makes your code easier to understand.
If you’re not familiar with arrow functions, they’re definitely worth learning. While they’re especially useful in this scenario, they also allow you to write much more succinct functions, which is applicable to many more scenarios. One other place they’re beneficial is paired with array methods! If you look at my filteredItems
function in Feature #4 , you can see I used an arrow function as the first argument of the filter
array method!
Wrapping up
Before I sign off, I want to talk about how I went about identifying these four improvements, and how you can learn to spot places that could use improvement in your codebase(s). Here are a few tips!
Look for repetition
Not all repetition is bad, but seeing anything repeated throughout your code should have you wondering if there is an opportunity for a good abstraction, or to learn a new pattern or language feature that solves the problem you’re working around.
Be aware of language changes
It would be impossible to know that you can simplify many of the loops in your code by using array methods if you didn’t keep up with the changes to JavaScript. That said, you don’t have to “dive deep” into every new thing, but try to have an awareness of what is available in the language you’re working with. Then, when you encounter a problem, hopefully you will be reminded of a language feature that solves the problem you’re facing.
Read other people’s code
If you work on a team, ask to review someone else’s code with them, or ask them to review yours. Seeing other people’s code, or their comments on yours, will allow you to learn how others do things differently. And when you see a code pattern you don’t recognize, figure out what it is and, if it makes sense, apply it to your code.
Further reading
- A Dead Simple Intro to Destructuring JavaScript Objects
- JavaScript: Arrow Functions for Beginners
- Podcast – 20 JavaScript Array and Object Methods to make you a better developer
Plug: LogRocket, a DVR for web apps
LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
The post Cleaning up your Vue.js code with ES6+ appeared first on LogRocket Blog.
Top comments (0)