I have just discovered Vue.js and I’ll never get back to jQuery!

I’m just enjoying the Vue. Photo by Simon Migaj from Pexels

Don’t blame me for being late for the party. The environment I lived in wasn’t properly configured so I could find this earlier and just shake off from all of the dust that was left off from jQuery during all these years.

I’m obsessed with how the code looks. I simply don’t push code that doesn’t make me proud, that doesn’t represent me. Every time I get the chance to make things better, I do. But for all these years, I struggled to understand something simpler than I thought — how fronted technologies revolutionized the entire way of building frontend.

What’s Vue.js?

Vue.js (pronounced [/vjuː/], just like the word view) is “a progressive framework for building user interfaces. Unlike other monolithic frameworks, Vue is designed from the ground up to be incrementally adoptable. The core library is focused on the view layer only and is easy to pick up and integrate with other libraries or existing projects. On the other hand, Vue is also perfectly capable of powering sophisticated Single-Page Applications when used in combination with modern tooling and supporting libraries.” (https://vuejs.org/v2/guide)

So, in other words, Vue.js allows us to build UIs without hassle, with minimum configuration, unlike other alternatives like jQuery, which we’ll be talking about in a few moments.

I’m not going to iterate through all the features that Vue.js offers us, but I’ll show you which ones made me give up on what I did so far and how messy it can be if you don’t switch to a modern frontend framework right now.

Before diving into the actual code, there are two fiddles I published, which are the final versions of each example and you can visualize the whole code — one in Vue.js and one in jQuery. Stick with this article, since the app is built progressively and you’ll understand how a new addition can trigger changes to our actual code.

So, let’s say you have a button that increments a number on each click, so you can show how many times that button got clicked.

In old HTML + jQuery suite, you’d do something like this:

<script>
var clicks = 0;
$('#my-button').on('click', function (e) {
e.preventDefault();
clicks++;
$(this).html(clicks + ' Clicks');
});
</script>
<button id="my-button">0 Clicks</button>

So, that’s nothing abnormal. You have a click counter variable at the top, a button with 0 Clicks HTML set by default and some code that listens on click events on that button increments the clicks counter and then changes the HTML value of the button to show the right value.

But what happens if you want to rename the button value from Clicks with Taps? You can do it by changing both Clicks within both code and button. So you’ll have to change in more places, which in this example looks minor, but for larger codebases, you’d spend more time changing multiple places for this minor naming change. We’ll see this later.

On the other side, in Vue.js, we can achieve the same behavior like this:

<div id="app">
<button @click="click()">
{{ clicks }} Clicks
</button>
</div>
<script>
new Vue({
el: "#app",
data: {
clicks: 0,
},
methods: {
click: function () {
this.clicks++;
},
},
});
</script>

Shorter, we have our app, the button listens to the click event with @click and will trigger the click() method defined in methods that will increment the clicks variable within data, that will render the variable {{ clicks }} within the button.

In this case, if we want to change from Clicks to Taps, we will have to replace only one word in the whole code, which makes changes easy.

So, let’s say that you want to add a Reset button so you would reset the clicks count. We’ll start, again, with jQuery and see how well it goes comparing to Vue.js:

<script>
var clicks = 0;
$('#reset-button').hide();$('#my-button').on('click', function (e) {
e.preventDefault();
clicks++;
if (clicks > 0) {
$('#reset-button').show();
}
$(this).html(clicks + ' Clicks');
});
$('#reset-button').on('click', function (e) {
e.preventDefault();
clicks = 0;
$('#my-button').html(clicks + ' Clicks');
$(this).hide();
});
</script>
<button id="my-button">0 Clicks</button>
<button id="reset-button">Reset</button>

It’s not the best thing we could achieve: we have a reset button, hidden by default, and when it is clicked, it will reset the clicks, change the HTML value of our initial button and hide, while on the initial button we add an if clause that only if we have at least one click we must show the reset button.

Remember the initial problem of changing code? Now it happens to change the word in three different places. Also, in the reset button click event, you must add code to hide the button, hence duplicating the .hide() method in two places.

Let’s have a look at the Vue.js version of this minimal app:

<div id="app">
<button @click="click()">
{{ clicks }} Clicks
</button>
<button v-if="clicks > 0" @click="reset()">
Reset
</button>
</div>
new Vue({
el: "#app",
data: {
clicks: 0,
},
methods: {
click: function () {
this.clicks++;
},
reset: function () {
this.clicks = 0;
}
},
});

We just added a new button that shows up only if we have at least one click, that triggers the reset() the method that does nothing but changes the clicks variable to 0. If we change the word Clicks with Taps it will still be only one change in the same place, while the jQuery version added one more place where we have to change the word Clicks.

Let’s bring this to a higher level. What if… we’d like to change the colors of the button based on how many clicks there are. For example, for odd numbers, we’ll set a red color and for even numbers, we’ll set a blue color?

In jQuery we’ll have to add more checkups:

<style>
.red {
background-color: red;
}
.blue {
background-color: blue;
}
</style>
<script>
var clicks = 0;
$('#reset-button').hide();
$('#my-button').addClass('blue');
$('#my-button').on('click', function (e) {
e.preventDefault();
clicks++;
if (clicks > 0) {
$('#reset-button').show();
}

if (clicks % 2 === 0) {
$(this).addClass('blue').removeClass('red');
} else {
$(this).addClass('red').removeClass('blue');
}
$(this).html(clicks + ' Clicks');
});
$('#reset-button').on('click', function (e) {
e.preventDefault();
clicks = 0;
$('#my-button').html(clicks + ' Clicks').removeClass('red').removeClass('blue');
$(this).hide();
});

Check for odds and even numbers on click, and remove the red class and add the blue class on even numbers, and vice-versa on odd numbers. Of course, let’s not forget that our reset button should reset the class back to blue since 0 is even (or we believe so), so we add removeClass('red').addClass('blue') . If you look closely, this bit of code is duplicated in two different places, which is another problem stacked on the old Clicks to Taps problem:

removeClass('red').addClass('blue')

Also, if our client doesn’t like the color that we chose, we have multiple places where we should change the code. Which again, stacks on… on every problem, we have so far.

In case you are now convinced that you should switch to Vue, I will give you a friendly reminder that there isn’t only Vue that does this. React and Angular are also two major frontend frameworks you should check them out too. They do the same thing. Before diving into this, check their documentation and examples and choose one that suits you.

I chose Vue.js because, for a Backend & DevOps person like me, it was the easiest thing on getting my head around to build full-stack apps as far as I work mostly with backend. The learning curve was in my favor. Also, it comes packaged in Laravel and is an on-the-go choice when working with it.

Going back to work, this is the previous example in Vue:

<style>
.red {
background-color: red;
}
.blue {
background-color: blue;
}
</style>
<div id="app">
<button v-bind:class="{ red: clicks % 2 === 1, blue: clicks % 2 === 0}" @click="click()">
{{ clicks }} Clicks
</button>
<button v-if="clicks > 0" @click="reset()">
Reset
</button>
</div>
new Vue({
el: "#app",
data: {
clicks: 0,
},
methods: {
click: function () {
this.clicks++;
},
reset: function () {
this.clicks = 0;
}
},
});

All we had to do was to add this bit of code on the initial button:

v-bind:class="{ red: clicks % 2 === 1, blue: clicks % 2 === 0 }"

This will set the red class if clicks is odd and the blue class if clicks is even. Just that. With just a little little bit of code, we achieved something that was done earlier in jQuery with more lines of code.

At the very end, we can see that there are two times more lines in the jQuery version (because of the code deduplication and useless rendering methods calls) than the Vue.js version of our simple clicky app.

Aftermath

So why is jQuery on a different island? Because jQuery works with DOM. It waits for it to be rendered and simple changes that, move that, and so forth. Directly within the DOM.

Vue is different. You work with data rather than DOM. In Vue.js, the DOM is rendered and updated using data, not by changing the DOM itself.

In case old habits die hard and you still choose jQuery over Vue.js or any kind of modern frontend framework, you can stay right there. There’s no hate I have for people that still work with jQuery.

The only thing I wanted to show up today was that there are reasons for choosing a modern way to build the frontend and how the past taught us lessons, thus making the present better.

Minimalist Laravel developer. Full stacking with AWS and Vue.js. Sometimes I deploy to Kubernetes. 🚢