Modern Tabs Powered By Vue.JS
By: Marcus Smith
Tags: JavaScript, Programming, Vue, Web Development, Web Framework

I am developing this custom transaction component for a client that will manage multiple different transaction types. We went into it with no question about the need for different tabs holding the different types. Initially I thought it was going to require some stupid grouping of the element IDs in a way that I could query and manipulate them. However, most of my experience and research had been before Vue and I remembered that Vue has some sneaky tools to simplify this. Now I could have each element respond of its own accord, individually updating a basic state variable and changing their styling with a binding connected to that variable.

The specific feature that I am advocating for today is Vue’s HTML class binding. And this is especially powerful when you are working on a group of dependently reactive elements like these tabs. First let’s talk about how I may have originally done this with basic JavaScript. (Disclaimer: I am not a “JavaScript Wizard”) There are likely better ways to do this that I am not aware of, but in basic JS I would have likely made my click function (attached to each tab) take the event target and modify its styling to fit the clicked tab, then have a list of all the tabs by ID that would be cycled to update the styling on the other tabs. It may look something like this (in Vue method format):

Possible Function for Relative Styling of Tabs

This may look fairly simple but remember that this extra code is cluttering up your click action (which should only manage events and state changes). Plus, don’t forget that you will have to keep a list of the different tab ids and make sure that you are keeping up with the styling that is sitting outside your CSS. I personally find this to be more like a hammer and less like a wrench.

Now, what can you do with Vue? If you aren’t familiar with Vue, or reactive frameworks in general, you may consider reading the Vue guide intro: https://vuejs.org/v2/guide/index.html . Otherwise, I suggest you look at the “Class & Style Bindings” portion: https://vuejs.org/v2/guide/class-and-style.html to get familiar with these specific concepts. I will specifically use class bindings to make my tabs simple & reactive. In short, these bindings allow CSS classes to be applied based on a component variable or computed property. In this example, we would write the elements something like this:

Vue HTML class binding for reactive styling

The key piece is the ~v-bind:class=“{**style** : **logic**}” ~ part. Inside of this declaration we are able to manipulate classes that can be added to our element. Allowing the style manipulation to be scoped to the element itself.

Basic CSS for unselected tabs

Our base tab class can have its normal styling as such, and we don’t have to directly manipulate element specific styling from outside. Then we just need to add a “tab-selected” class that the binding manipulates based on the state of the application. This selected class will only hold the style manipulation specific to the selected tab. Add this to the binding in front of the colon (single quotes if it is kebab-case): ~v-bind:class=“{‘tab-selected’:**logic**}”~.

Style changes for the selected tab

With the styling all settled out the last piece is adding in the basic logic necessary to manage state for the tabs. For this we will go back to the click event first. Because Vue is state based, we want to have a variable that holds the ID of the current selected tab. I have called this state variable “currentTab”. When the tab is clicked, we just need the click event to update that variable to reflect the state change. It should look something like this:

Just like in the generic JS, we are able to use events to retrieve the id of the tab that was clicked, but now we are saving it in the state. Once that state is updated on the click event, the Vue reactivity updates all of the bindings that include the “currentTab” variable. Because we now know what the current tab’s ID is, we can have each element binding check if it owns that ID. Making our binding look like above ~v-bind:class=“{‘tab-selected’:currentTab==’credCard’}”~, where Vue sees the state change and adds/removes the class based on the binding logic. The nice part is that Vue sets the bound class after the static class, allowing for an intuitive override in situations like this.

So by using Vue.JS as our web framework and taking advantage of the class binding feature, we are able to make a more complex UI element quite simple and well organized, where it may have been less so in the past. Am I an advocate for Vue? For sure, and I will hopefully be posting much more about my experiences with Vue as I use it for most of my development. However, given my lack of knowledge in other frameworks, I am not going to say it’s the best or that this can’t be done by others. What I will say is that if you haven’t considered moving to a modern web framework, I highly suggest you consider doing so. It has made development seem much simpler and fun and I have found Vue specifically to be quite easy to pick up quickly.

If you found the concepts confusing starting out, that’s ok. I felt the same way, especially with some of the more complex state based logic that Vue offers. However, it really is an elegant way to manage reactive pages and provides a lightning fast experience for users. Hopefully you will find it to be as good of an experience as I have after some time developing in Vue. Forgive me if I could have presented the concepts better, I am new to documenting my learning and experiences. Please feel free to say something and Hopefully I can continue to improve as I move forward.

Thanks for taking the time to read this; -Marcus