Refactoring Vue.js code

Minul Lamahewage
Arimac
Published in
4 min readNov 13, 2020
Photo by Emile Perron on Unsplash

Refactoring code is never fun but it can be less of a pain. Following general methods for various problems you may face while trying to refactor Vue.js code can make life a lot easier.

Here are some of the methods I used while refactoring Vue 2 code.

Extracting methods

Extracting methods/functions common across several Vue components.

Here is a sample Vue component.

Say we have several components that have the same method “testMethod1”. To extract this method, create the same function in a separate JavaScript file and export it. Then import that JavaScript file into the Vue components and reference that function as the method. A sample code is given below.

If the method you need to extract also needs to reference the component, then pass the component to the function and receive it as a parameter with a different keyword. That is,

//vue component
methods: {
testMethod1: function(){
testMethod1(this)
}
}
//js file
export testMethod1(that){
//method content
}

Creating child components

Say you’ve created a single or several large components with a lot of elements inside them. It’s generally considered best practice to separate it out into child components such that each child component has a singular purpose. When doing this one of the issues you may face is the passing of data between the parent and the child components.

To pass down data from parent to child you use props.
To pass up data from child to parent you use custom events.

The use of props is quite straightforward. The Vue.js documentation does a good job of explaining props, which is referenced below.

Passing data from child to parent

When you need to pass data back up to the parent you need to use custom events. These custom events need to be fired by events from the elements within the child component. For example, take a text field. To pass the input from this text field you could use the “change” event to fire the custom event. Then, the parent will listen to this custom event and receive the data from it.

//child component
<template>
<v-text-field
label="textLabel"
outlined
@change
= "updateName"
></v-text-field>
</template>
//methods
updateName($event){
this.$emit("updateNameChild", $event)
}
//parent component
<ChildComponent
@updateNameChild = "updateNameParent"
/>
//methods
updateNameParent($event){
//method content
//$event is the input from v-text-field
}

Two way binding of data

Say there is a property “name” in data of the parent. This property needs to be two way bounded with the child component. For example, the child component may have a text field that updates this “name” property while other methods in the parent may also change the value of “name” and this needs to be reflected in the text field in the child component. To achieve this proper two binding is needed.
One way to do this is to use the two methods mentioned above and manually update the data of the parent using the “updateNameParent” method.
But Vue has another solution for this.

.sync modifier

Using this removes the need to have another method in the parent that is called when the event is fired from the child.

As you can see the “updateName” method in the parent can be removed.
This method achieves two-way binding. The event that is fired from the child needs to have the following syntax “update:{prop name}”. That is how the parent identifies it. More details can be found in the Vue documentation linked above.

One thing to take note of is that the .sync modifier can be used only for one level of data binding. If this data has to be bound among several levels of child components, then the first method has to be followed for all of the other levels.

As a side note, Vue doesn’t allow the use of v-model for two way binding. The method given above is the one that is recommended.

Extracting data

There may be several components that have a common data property which has a rather long value. In this case, you can extract it out into a separate javascript function that returns the value when called.

The function dataProperty() has to be called and the value for dataProperty assigned inside created() if the component needs that property as it is created. It can’t be done inside mounted().

Extracting out an entire data object

Say there are several components that have nearly identical data objects. Then you can extract this out if for example, you need consistency between the data objects among all these components. Extracting it out into a single place lets us make changes to the code in only one place.

To do this you need to create a javascript function that returns the data object when called.

Then it has to be imported in the relevant components with the correct parameters. The data function in the Vue component has to return this function(get_data) while calling it.

If all the components have identical data objects then the passing of a parameter isn’t necessary.

These are some of the ways you can refactor Vue code by modularizing it.

I hope this helps you get a general understanding of each technique and saves you the pain of having to search for each one separately.

--

--

Minul Lamahewage
Arimac
Writer for

3rd year Computer Science and Engineering undergraduate at University of Moratuwa, Sri Lanka