3 Ways to Implement the same functionality with Vue 3 + Vite

3 Ways to Implement the same functionality with Vue 3 + Vite

If you're beginning to learn Vue.js, specifically Vue 3 in late 2021, this post will help you avoid some pitfalls that I spent time resolving and get you started quickly.


I'm primarily a Python 3 backend developer. I have some experience building server-rendered applications using Flask and FastAPI. I've had some exposure to React and jquery. I have also built some apps using Node.js so I'm fairly comfortable with Javascript. CSS has been my Achilles' heel. I have some backend projects that I want to create frontends for and was avoiding learning the newer frontend technologies. I can make apps, but they look pretty crappy. So I finally decided to delve into learning CSS properly and came across Bulma. Within a day I was able to create a fairly good-looking app.

Now I wanted to add some interactivity. I've experienced React before and it was messy for me. I wanted to learn something easy and provide immediate results. I eventually decided that Vue will be the better option for me.

One of the main pains I experienced, that kept me from doing front-end stuff was this entire stack of build tools that you need to configure. If I had my way, I'd just want to add the frameworks in a plain HTML file and avoid using any build tools. But I like Hot Module Reloading. I used browsersync to just play with a plain hand-coded HTML page. But as Vue came into the picture, I discovered Vite. And man 0h man. It's great. Simple. Fast.

What I was doing

I built a basic CSS front-end with Bulma by manually building Vue components with the base vue template that comes with vite. I needed to add some simple pieces of interactivity in the toy example I was working with.

  1. Clicking the hamburger menu opens up the menu on a mobile screen

2.    Clicking a link in the menu shows the modal window

3.   Clicking the close button on the modal hides the modal window

What confused me

The complexity occurred when I reached the point of communicating events between parent and child components.

You see, most of the Vue documentation and introductory tutorials available on the website describe building a vue root instance and vue components in pure Javascript. The vite generated scaffolding on the other hand uses Single File Components (SFC). SFC's are great. In the script section of an SFC, you basically describe the component using the Options API. This is very similar to what you learn in the introductory tutorials. With a little bit of trial and error, I was able to figure it out and had the interactivity with the hamburger menu on a mobile device implemented.

However, when I started implementing the second feature: showing the modal window, there was inter-component communication and the root vue instance was described in a script setup tag (which is what vite generates by default). I attempted to build an Options API-based object but couldn't figure it out.

I started searching for internet resources that will describe how to build Vue applications with vite and finally, after watching a few Youtube videos and going through the documentation a few times I got it.

The problem was that the new Vue 3 syntax uses something called Composition API. None of this was described in the introductory examples and tutorials so I had no idea.

What I learned

Finally, I implemented the root vue component in three different flavors to achieve the same thing.

Here are those three ways:

Vue Composition API in a script tag with the setup attribute. Syntactic sugar 🍭
Composition API with the explicit setup method
Traditional Options API


This was an interesting learning exercise. My initial hesitation with going with a Javascript framework was to avoid complex build setups. I realized Vue could be used within the server-rendered application to sprinkle some lightweight interactivity. However, as with any tool, I spent a good bunch of time understanding and setting up tooling to be functional. Vite with Vue turned out to be a good balance that I can be happy with.

I continue to post my learnings on Twitter if you'd like to follow me on my journey.